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

адреса — численные выражения в квадратных скобках (учитывая оператор размерности и префикс сегмента)

мнемоники инструкций

регистры

операторы размерности

операторы >NEAR и >FAR

операторы >USE16 и >USE32

пустые аргументы (пробелы, символы табуляции)

Пример макроса, который позволяет использовать переменную в памяти в качестве счётчика в инструкции >SHL (например >shl ax, [myvar]):

>macro shl dest, count

>{

> if count eqtype [0]  ;если count — ячейка памяти

>  push cx

>  mov cl, count

>  shl dest, cl

>  pop cx

> else             ;если count другого типа

>  shl dest, count ;просто используем обычную shl

> end if

>}

>shl ax, 5

>byte_variable db 5

>shl ax, [byte_variable]

получится:

>if 5 eqtype [0]

> push cx

> mov cl, 5

> shl ax, cl

> pop cx

>else

> shl ax, 5

>end if

>byte_variable db 5

>if [byte_variable] eqtype [0]

> push cx

> mov cl, [byte_variable]

> shl ax, cl

> pop cx

>else

> shl ax, [byte_variable]

>end if

в результате обработки условий конечный результат будет:

> shl ax, 5

>byte_variable db 5

> push cx

> mov cl, [byte variable]

> shl ax, cl

> pop cx

Заметьте, что >shl ax, byte [myvar] не будет работать с этим макросом, так как условие >byte [variable] eqtype [0] не выполняется. Читаем дальше.

Когда мы сравниваем что-то посредством >EQTYPE, то это что-то может быть не только единичным идентификатором, но и их комбинацией. В таком случае, результат >eqtype истина, если не только типы, но и порядок идентификаторов совпадают. К примеру, >if eax 4 eqtype ebx name — верно, так как >name — это метка, и её тип — численное выражение.

Пример расширенной инструкции >mov, которая позволяет перемещать данные между ячейками памяти:

>macro mov dest,src

>{

> if dest src eqtype [0] [0]

>  push src

>  pop dest

> else

>  mov dest,src

> end if

>}

>mov [var1], 5

>mov [var1], [var2]

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

>if [var1] 5 eqtype [0] [0] ;не верно

> push 5

> pop [var1]

>else

> mov [var1],5

>end if

>if [var1] [var2] eqtype [0] [0] ;верно

> push [var2]

> pop [var1]

>else

> mov [var1], [var2]

>end if

и будет ассемблировано в:

> mov [var1], 5

> push [var2]

> pop [var1]

Хотя более удобно для восприятия реализовать макрос используя логический оператор И>&:

>macro mov dest,src

>{

> if (dest eqtype [0]) & (src eqtype [0])

>  push src

>  pop dest

> else

>  mov dest, src

> end if

>}

Пример с использованием >EQTYPE с четырьмя аргументами приведён для демонстрации возможностей, обычно проще использовать в таких случаях >&. Кстати, в качестве аргументов, возможно использовать некорректные выражения — достаточно, чтобы лексический анализатор распознал их тип. Но это не является документированным, так что не будем этот обсуждать.

7.3. Оператор IN

Бывают случаи, когда в условии присутствует слишком много