Руководство по препроцессору FASM - страница 6
, >|
и т. п.) — RTFM. Я лишь расскажу об операторах проверки условия используемых препроцессором.
7.1. Оператор EQ
Простейший логический оператор — это >EQ
. Он всего лишь сравнивает два идентификатора — одинаковы ли их значение. Значение >abcd eq abcd
— истина, а >abcd eq 1
— ложь и так далее… Это полезно для сравнения символов, которые будут обработаны препроцессором:
>STRINGS equ ASCII
>if STRINGS eq ASCII
> db 'Oh yeah',0
>else if STRINGS eq UNICODE
> du 'Oh yeah',0
>else
> display 'unknown string type'
>end if
после обработки препроцессором, это примет вид:
>if ASCII eq ASCII
> db 'Oh yeah',0
>else if ASCII eq UNICODE
> du 'Oh yeah',0
>else
> display 'unknown string type'
>end if
Здесь только первое условие (>ASCII eq ASCII
) выполняется, так что будет ассемблировано только >db 'Oh yeah',0
Другой вариант:
>STRINGS equ UNICODE ;разница здесь, UNICODE вместо ASCII
>if STRINGS eq ASCII
> db 'Oh yeah',0
>else if STRINGS eq UNICODE
> du 'Oh yeah',0
>else
> display 'unknown string type'
>end if
получим:
>if UNICODE eq ASCII
> db 'Oh yeah',0
>else if UNICODE eq UNICODE
> du 'Oh yeah',0
>else
> display 'unknown string type'
>end if
Тут уже первое условие (>UNICODE eq ASCII
) будет ложно, второе (>UNICODE eq UNICODE
) — верно, будет ассемблироваться >du 'Oh yeah',0
.
Несколько лучшее применение этого — проверка аргументов макросов, вроде:
>macro item type,value
>{
> if type eq BYTE
> db value
> else if type eq WORD
> dw value
> else if type eq DWORD
> dd value
> else if type eq STRING
> db value,0
> end if
>}
>item BYTE,1
>item STRING,'aaaaaa'
будет:
>if BYTE eq BYTE
> db 1
>else if BYTE eq WORD
> dw 1
>else if BYTE eq DWORD
> dd 1
>else if BYTE eq STRING
> db 1,0
>end if
>if STRING eq BYTE
> db 'aaaaaa'
>else if STRING eq WORD
> dw 'aaaaaa'
>else if STRING eq DWORD
> dd 'aaaaaa'
>else if STRING eq STRING
> db 'aaaaaa',0
>end if
ассемблироваться будут только 2 команды:
>db 1
>db 'aaaaaa',0
Подобно всем другим операторам препроцессора, >EQ
может работать с пустыми аргументами. Это значит, что, например, >if eq
верно, а >if 5 eq
— ложно и т. п.
Пример макроса:
>macro mov dest,src,src2
>{
> if src2 eq
> mov dest, src
> else
> mov dest, src
> mov src, src2
> end if
>}
здесь, если есть третий аргумент, то будут ассемблироваться 2 последних команды, если нет — то только одна первая.
7.2. Оператор EQTYPE
Ещё один оператор — >EQTYPE
. Он определяет, одинаков ли тип идентификаторов.
Существующие типы:
отдельные строки символов, заключённые в кавычки (те, которые не являются частью численных выражений)
вещественные числа (с плавающей точкой)
любые численные выражения, например, >2+2
(любой неизвестный символ будет рассматриваться как метка, так что он будет считаться подобным выражением)
адреса — численные выражения в квадратных скобках (учитывая оператор размерности и префикс сегмента)
мнемоники инструкций
регистры
операторы размерности
операторы >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
— это метка, и её тип — численное выражение.