Руководство по препроцессору FASM (fb2) читать постранично, страница - 3
[Настройки текста] [Cбросить фильтры]
- 1
- 2
- 3
- 4
- 5
- . . .
- последняя (7) »
5. Макросы с фиксированным количеством аргументов
5.1. Макросы с одним аргументом
Макросы могут иметь аргумент. Аргумент представляет собой какой-либо идентификатор, который будет повсюду заменён в теле макроса тем, что будет указанно при использовании. Синтаксис: macro name argument { тело макроса } Например: macro add5 where { add where, 5 } add5 ax add5 [variable] add5 ds add5 ds+2 получим: add ax, 5 add [variable], 5 add ds, 5 ;такой инструкции не существует ;но препроцессор это не волнует. ;ошибка появится на стадии ассемблирования. add ds+2,5 ;ошибка синтаксиса, как и ранее ;определится при анализе синтаксиса (parsing). (разумеется, комментарии в результате работы препроцессора не появятся:)5.2. Макросы с несколькими аргументами
У макросов может быть несколько аргументов, разделённых запятыми, macro movv where, what { push what pop where } movv ax, bx movv ds, es movv [var1], [var2] преобразуется в: push bx pop axpush es pop ds
push [var2] pop [var1] Если несколько аргументов имеют одно и тоже имя, то будет использован первый из них:). Если при использовании макроса указать меньше аргументов, чем при определении, то значения неуказанных будет пустым: macro pupush a1, a2, a3, a4 { push a1 a2 a3 a4 pop a4 a3 a2 a1 } pupush eax, dword [3] получим: push eax dword [3] pop dword [3] eax Если в аргументе макроса необходимо указать запятую, необходимо аргумент заключить в скобочки из символов < и >. macro safe_declare name, what { if used name name what end if}
safe_declare var1, db 5 safe_declare array5, <dd 1,2,3,4,5> safe_declare string, <db "привет, я просто строка",0> получим: if used var1 var1 db 5 end if
if used array5 array5 dd 1,2,3,4,5 end if
if used string string db "привет, я просто строка",0 end if Конечно же, можно использовать символы < и > и внутри тела макроса: macro a arg {db arg} macro b arg1,arg2 {a <arg1,arg2,3>} b <1,1>,2 получим: db 1,1,2,3
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:5.4. Оператор объединения #
У макроязыка FASMа есть ещё одна возможность —- 1
- 2
- 3
- 4
- 5
- . . .
- последняя (7) »
Последние комментарии
7 часов 5 минут назад
7 часов 19 минут назад
8 часов 27 минут назад
19 часов 45 минут назад
20 часов 3 минут назад
20 часов 27 минут назад