Руководство по препроцессору FASM - страница 2

стр.

>

>mov ecx, count

преобразуется в:

>mov eax, count

>mov ecx,10

потому что препроцессор заменит >count только после директивы >equ.

Даже это работает:

>10 equ 11

>mov ecx, 10

после обработки препроцессором, получим:

>mov ecx, 11

Обратите внимание, >name1 может быть любым идентификатором. Идентификатор — это всего лишь набор символов, завершаемый пробелом (space), символом табуляции (tab), концом строки (EOL), комментарием >;, символом переноса строки >\ или оператором, включая операторы ассемблера и/или специальные символы вроде >, или >}.

>name2 может быть не только единичным идентификатором, берутся все символы до конца строки. >name2 может и отсутствовать, тогда >name1 будет заменен на пустое место.

Например:

>10 equ 11, 12, 13

>db 10

получим:

>db 11, 12, 13

3.2. Директива RESTORE

Можно заставить препроцессор прекратить заменять идентификаторы, определённые директивой >EQU. Это делает директива >RESTORE.

Синтаксис:

>restore name1

>name1 — это идентификатор определённый ранее в директиве >EQU. После этой команды name больше не будет заменяться на >name2.

Например:

>mov eax, count

>count equ 10

>mov eax, count

>restore count

>mov eax, count

получим:

>mov eax, count

>mov eax, 10

>mov eax, count

Обратите внимание, что для определений сделанных директивой >EQU работает принцип стека. То есть, если мы два раза определим один и тот же идентификатор используя >EQU, то после однократного использования >RESTORE значение идентификатора будет соответствовать определённому первой директивой >EQU.

Например:

>mov eax, count

>count equ 1

>mov eax, count

>count equ 2

>mov eax, count

>count equ 3

>mov eax, count

>restore count

>mov eax, count

>restore count

>mov eax,count

>restore count

>mov eax,count

получим:

>mov eax, count

>mov eax, 1

>mov eax, 2

>mov eax, 3

>mov eax, 2

>mov eax, 1

>mov eax, count

Если попытаться выполнить >RESTORE большее количество раз, чем было сделано >EQU, никаких предупреждений выдано не будет. Значение идентификатора будет неопределенно.

Например:

>mov eax, count

>restore count

>mov eax, count

получим:

>mov eax, count

>mov eax, count

4. Простые макросы без аргументов

4.1. Определение простых макросов

Использую >EQU можно делать наиболее простые замены в исходном тексте при обработке препроцессором. Большими возможностями обладают макросы. Командой >MACRO можно создавать собственные инструкции.

Синтаксис:

>macro name

>{

>; тело макроса

>}

Когда препроцессор находит директиву >macro, он определяет макрос с именем >name. Далее, встретив в исходном тексте строку, начинающуюся с >name, препроцессор заменит >name на тело макроса — то, что указано в определении между скобочками >{ и >}. Имя макроса может быть любым допустимым идентификатором, а тело макроса — всё, что угодно, за исключением символа >}, который означает завершение тела макроса.

Например:

>macro a

>{

> push eax

>}

>xor eax, eax

> a

будет заменено на:

>xor eax, eax

>push eax

Или:

>macro a

>{

> push eax

>}

>macro b

>{

> push ebx

>}

>b

>a

получим:

>push ebx

>push eax

Разумеется, макросы не обязательно оформлять так, как выше, можно делать и так:

>macro push5 {push dword 5}

>push5

получим:

>push dword 5

Или:

>macro push5 {push dword 5

>}

с тем же самым результатом. Скобочки можете размещать как хотите.

4.2. Вложенные макросы

Макросы могут быть вложенными один в другой. То есть, если мы переопределим макрос, будет использовано последнее определение. Но если в теле нового определения содержится тот же макрос, то будет использовано предыдущее определение. Посмотрите пример:

>macro a {mov ax, 5}

>macro a

>{

> a

> mov bx, 5

>}

>macro a

>{

> a

> mov cx, 5

>}

>a

в результате получим:

>mov ax, 5

>mov bx, 5

>mov cx, 5

Или такой пример:

>macro a {1}

>a

>macro a {

> a

> 2 }

>a

>macro a {

> a

> 3 }

>a

получим:

>1

>1

>2

>1

>2

>3

4.3. Директива PURGE. Отмена определения макроса

Как и в случае с директивой >EQU, можно отменить определение макроса. Для этого используется директива >PURGE с указанием имени макроса.

Синтаксис:

>purge name

Пример:

>a

>macro a {1}

>a

>macro a {2}

>a

>purge a

>a

>purge a

>a

получим:

>a

>1

>2

>1

>a

Если применить >PURGE к несуществующему макросу, ничего не произойдёт.

4.4. Поведение макросов

Имя макроса будет заменено его телом не только в том случае, если оно расположено в начале строки. Макрос может находиться в любом месте исходного текста, где допустима мнемоника инструкции (например,