:
>macro mov a,b
>{
> if (a eq cs) | (a eq ds) | (a eq es) | (a eq fs) | \
> (a eq gs) | (a eq ss)
> push b
> pop a
> else
> mov a, b
> end if
>}
Вместо применения множества логических операторов ИЛИ — >|
, можно использовать специальный оператор >IN
. Он проверяет, присутствует ли идентификатор слева, в списке идентификаторов справа. Список должен быть заключён в скобочки ><
и >>
, а идентификаторы в нём разделяются запятыми,
>macro mov a,b
>{
> if a in
> push b
> pop a
> else
> mov a, b
> end if
>}
Это так же работает для нескольких идентификаторов (как и >EQ
):
>if dword [eax] in <[eax], dword [eax], ptr eax, dword ptr eax>
В FASM, структуры практически тоже самое, что и макросы. Определяются они посредством директивы >STRUC
:
Синтаксис:
>struc name arguments { тело структуры }
Отличае от макросов заключается в том, что в исходном тексте перед структурой должна находиться метка — имя объекта-структуры. Например:
>struc a {db 5}
>a
это не будет работать. Структуры распознаются только после меток, как здесь:
>struc a {db 5}
>name a
подобно макросу, это преобразуется препроцессором в:
>db 5
Смысл метки в следующем — она будет добавлена ко всем идентификаторам из тела структуры, которые начинаются с точки… Например:
>struc a {.local:}
>name1 a
>name2 a
будет:
>name1.local:
>name2.local:
Таким образом можно создавать структуры вроде тех, что есть в других языках:
>struc rect left,right,top,bottom ;аргументы как у макроса
>{
> .left dd left
> .right dd right
> .top dd top
> .bottom dd bottom
>}
>r1 rect 0,20,10,30
>r2 rect ?,?,?,?
получим:
>r1.left dd 0
>r1.right dd 20
>r1.top dd 10
>r1.bottom dd 30
>r2.left dd ?
>r2.right dd ?
>r2.top dd ?
>r2.bottom dd ?
Поскольку, используемой структуре всегда должна предшествовать метка, препроцессор однозначно отличает их от макросов. Поэтому имя структуры может совпадать с именем макроса — в каждом случае будет выполняться нужная обработка.
Существуют хитрый приём, позволяющий не указывать аргументы, если они равны >0
:
>struc ymmv arg
>{
> .member dd arg+0
>}
>y1 ymmv 0xACDC
>y2 ymmv
будет:
>y1.member dd 0xACDC+0
>y2.member dd +0
Как говорилось ранее, если значение аргумента не указанно, то в теле макроса или структуры вместо него ничего не подставляется. В этом примере >+
используется или как бинарный (то есть с двумя операндами), или как унарный (с одним операндом) оператор.
ПРИМЕЧАНИЕ: часто используется так же макрос или структура >struct
, которая определяется для расширения возможностей при определении структур. Не путайте >struct
и >struc
.
9. Оператор FIX и макросы внутри макросов
В стародавние времена, в FASMе отсутствовала одна полезная возможность — создавать макросы внутри других макросов. Например, что бы при развёртывании макроса был бы определён новый макрос. Что-то вроде гипотетичного: