string_table 'aaaaa','bbbbbb','5'
получим:
dd addr?00000001
dd addr?00000002
dd addr?00000003
addr?00000001 db 'aaaaa',0
addr?00000002 db 'bbbbbb',0
addr?00000003 db '5',0
Другой пример с блоком REVERSE
macro a [x]
{
forward
local here
here db x
reverse
dd here
}
a 1,2,3
будет:
here?00000001 db 1
here?00000002 db 2
here?00000003 db 3
dd here?00000003
dd here?00000002
dd here?00000001
Как видно, метки используется с соответствующими аргументами и в FORWARD
REVERSE
блоках.6.7. Макросы с несколькими групповыми аргументами
Возможно использовать и несколько групповых аргументов. В этом случае определение макроса не будет выглядеть как:
macro a [grp1],[grp2]
так как тут не ясно какой аргумент какой группе принадлежит. Исходя из этого делают так:
Синтаксис:
macro a [grp1,grp2]
В этом случае каждый нечётный аргумент относится к группе grp1
grp2
:macro a [grp1,grp2]
{
forward
l_#grp1:
forward
l_#grp2:
}
a 1,2,3,4,5,6
будет:
l_1:
l_3:
l_5:
l_2:
l_4:
l_6:
Или ещё:
macro ErrorList [name,value]
{
forward
ERROR_#name = value
}
ErrorList \
NONE,0,\
OUTOFMEMORY,10,\
INTERNAL,20
получим:
ERROR_NONE = 0
ERROR_OUTOFMEMORY = 10
ERROR_INTERNAL = 20
Конечно же, может быть больше 2х групп аргументов:
macro a [g1,g2,g3]
{
common
db g1
db g2
db g3
}
a 1,2,3,4,5,6,7,8,9,10,11
будет:
db 1,4,7,10
db 2,5,8,11
db 3,6,9
7. Условный препроцессинг
В действительности, FASM не имеет директив для условного препроцессинга. Но директива ассемблера if
Как известно, оператор if
Я не буду рассказывать о деталях времени ассемблирования (логических операциях вроде &
|
и т. п.) — 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