5.3. Директива LOCAL
Возможно, появится необходимость объявить метку внутри тела макроса:
macro pushstr string
{
call behind ; помещаем в стек адрес string и переходим к behind
db string, 0
behind:
}
но если использовать такой макрос 2 раза, то и метка behind будет объявлена дважды, что приведёт к ошибке. Эта проблема решается объявлением локальной метки behind. Это и делает директива LOCAL.
Синтаксис:
local label_name
Директива должна применяться внутри тела макроса. Все метки label_name внутри макроса становятся локальными. Так что, если макрос используется дважды никаких проблем не появляется:
macro pushstr string
{
local behind
call behind
db string,0
behind:
}
pushstr 'aaaaa'
pushstr 'bbbbbbbb'
call something
На самом деле, behind заменяется на behind?XXXXXXXX, где XXXXXXXX — какой-то шестнадцатеричный номер генерируемый препроцессором. Последний пример может быть преобразован к чему-то вроде:
call behind?00000001
db 'aaaaa', 0
behind?00000001:
call behind?00000002
db 'bbbbbbbb', 0
behind?00000002:
call something
Заметьте, Вы не сможете напрямую обратиться к метке содержащей ? так как это специальный символ в FASM, поэтому он и используется в локальных метках. К примеру, aa?bb рассматривается как идентификатор aa, специальный символ ? и идентификатор bb.
Если Вам нужно несколько локальных меток — не проблема, их можно указать в одной директиве LOCAL, разделив запятыми ,:
macro pushstr string ; делает то же, что и предыдущий макрос
{
local addr, behind
push addr
jmp behind
addr db string,0
behind:
}
Всегда хорошо бы начинать все локальные метки макросов с двух точек .. — это значит, что они не будут менять текущую глобальную метку. К примеру:
macro pushstr string
{
local behind
call behind
db string, 0
behind:
}
MyProc:
pushstr 'aaaa'
.a:
будет преобразовано в:
MyProc:
call behind?00000001
db 'aaaa', 0
behind?00000001:
.a:
в результате получим метку behind?00000001.a вместо MyProc.a. Но если в примере выше behind заменить на ..behind, текущая глобальная метка не изменится и будет определена метка MyProc.a:
macro pushstr string
{
local ..behind
call ..behind
db string,0
..behind:
}
MyProc:
pushstr 'aaaa'
.a:
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК