count equ 10
mov ecx, count
преобразуется в:
mov eax, count
mov ecx,10
потому что препроцессор заменит count
equ
.Даже это работает:
10 equ 11
mov ecx, 10
после обработки препроцессором, получим:
mov ecx, 11
Обратите внимание, name1
;
, символом переноса строки \
или оператором, включая операторы ассемблера и/или специальные символы вроде ,
или }
.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