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

>r_2:

>r_1:

6.6. Директива LOCAL в макросах с групповыми аргументами

У локальных меток в макросах есть ещё одно полезное свойство. Если директива >LOCAL находится внутри блока >FORWARD или >REVERSE, то уникальное имя метки сгенерируется для каждого аргумента из группы, и в последующих блоках >FORWARD и/или >REVERSE для каждого аргумента будет использована соответствующая ему метка:

>macro string_table [string]

>{

> forward           ;таблица указателей на строки

>  local addr       ;локальная метка для строки

>  dd addr          ;указатель на строку

> forward           ;строки

>  addr db string,0 ;создаём и завершаем нулём

>}

>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 обрабатывается во время ассемблирования. Это значит, что условие в этом операторе проверяется после обработки исходного текста препроцессором. Именно это обеспечивает работу некоторых логических операций.

Я не буду рассказывать о деталях времени ассемблирования (логических операциях вроде