адреса — численные выражения в квадратных скобках (учитывая оператор размерности и префикс сегмента)
мнемоники инструкций
регистры
операторы размерности
операторы >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
с четырьмя аргументами приведён для демонстрации возможностей, обычно проще использовать в таких случаях >&
. Кстати, в качестве аргументов, возможно использовать некорректные выражения — достаточно, чтобы лексический анализатор распознал их тип. Но это не является документированным, так что не будем этот обсуждать.