Макросы и директивы компилятора FASM | страница 3



>macro movstr

> {

>      local move

>  move:

>      lodsb

>      stosb

>      test al,al

>      jnz move

> }

При использовании этого макроса метка >move всегда имеет свое уникальное значение и повторение этого макроса не вызовет ошибок.

Директивы >forward, >reverse и >common делят макрос на блоки, каждый обрабатывается после того, как обработка предыдущих закончена. Они отличаются по поведению, только если макрос позволяет множественные группы аргументов. Блок инструкций, что следует за директивой >forward, будет обработан для каждой группы аргументов с первого до последнего — наподобие обычному блоку (не заданному в соответствии с любой из этих директив). Блок, который следует за директивой >reverse, будет обработан для каждой группы аргумента в обратном порядке — от последнего до первого. Блок, который следует за директивой >common, будет обработан только однажды, сразу для всех групп аргументов. Значение >local, определенное в одном из блоков доступно во всех следующих блоках при обработке той же самой группы аргументов где оно было определено, когда оно определено в блоке >common, оно доступно во всех следующих блоках независимо какая группа аргументов обрабатывается.

Вот пример макроса, который создаст таблицу адресов к строкам, заданных этими строками:

>macro strtbl name,[string]

> {

>  common

>      label name dword

>  forward

>      local label

>      dd label

>  forward

>      label db string,0

> }

Первый аргумент, переданный этому макросу, станет меткой для таблицы адресов, следующие аргументы должны быть строками. Первый блок обрабатывается только один раз и определяет метку, второй блок для каждой строки объявляет ее локальное имя и определяет запись таблицы, содержащую адрес той строки. Третий блок определяет данные каждой строки с соответствующей меткой. Директива, начинающая блок в макросе может сопровождаться первой инструкцией этого блока на той же самой строке, как показано в следующем примере:

>macro stdcall proc,[arg]

> {

>  reverse >push arg

>  common >call proc

> }

Этот макрос может использоваться для вызова процедур, использующих соглашение STDCALL, где аргументы сохраняются на стек в обратном порядке. Для примера >stdcall foo, 1,2,3 будет собран как:

>push 3

>push 2

>push 1

>call foo

Если некоторое имя в макросе имеет множественные параметры (одним из аргументов, огороженных в квадратные скобки или локальным именем, определенным в блоке, следующем за директивой >forward или >reverse) и используется в блоке, следующем за директивой common, это имя будет заменено всеми ее величинами, отделенными запятыми. Например следующий макрос передаст все дополнительные аргументы предварительно заданному макросу