Руководство по препроцессору FASM (Неизвестен) - страница 5

5.2. Макросы с несколькими аргументами

У макросов может быть несколько аргументов, разделённых запятыми,

>macro movv where, what

>{

> push what

> pop where

>}

>movv ax, bx

>movv ds, es

>movv [var1], [var2]

преобразуется в:

>push bx

>pop ax


>push 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,

>safe_declare string,

получим:

>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 }

>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.

Если Вам нужно несколько локальных меток — не проблема, их можно указать в одной директиве