Как и в случае с директивой >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
к несуществующему макросу, ничего не произойдёт.
Имя макроса будет заменено его телом не только в том случае, если оно расположено в начале строки. Макрос может находиться в любом месте исходного текста, где допустима мнемоника инструкции (например, >add
или >mov
). Всё потому, что основное предназначение макросов — имитировать инструкции. Единственное исключение из этого правила — макросы недопустимы после префиксов инструкций (>rep
).
Пример:
>macro CheckErr
>{
> cmp eax, -1
> jz error
>}
> call Something
>a: CheckErr ; здесь макросу предшествует метка, всё Ок.
получим:
> call Something
>a: cmp eax,-1
> jz error
Пример № 2:
>macro stos0
>{
> mov al, 0
> stosb
>}
> stos0 ;это место инструкции, будет замена.
>here: stos0 ;это тоже место инструкции.
> db stos0 ;здесь инструкции не место, замены не будет.
получим:
> mov al, 0
> stosb
>here: mov al, 0
> stosb
> db stos0
Возможно переопределять (overload) инструкции посредством макросов. Так как препроцессор ничего об инструкциях не знает, он позволяет использовать мнемонику инструкции в качестве имени макроса:
>macro pusha
>{
> push eax ebx ecx edx ebp esi edi
>}
>macro popa
>{
> pop edi esi ebp edx ecx ebx eax
>}
эти 2 новые инструкции будут экономить по 4 байта в стеке, так как не сохраняют >ESP
(правда, занимают побольше места, чем реальные инструкции:). Всё же, переопределение инструкций не всегда хорошая идея — кто-нибудь читая Ваш код может быть введён в заблуждение, если он не знает, что инструкция переопределена.
Также, возможно переопределять директивы ассемблера:
>macro use32
>{
> align 4
> use32
>}
>macro use16
>{
> align 2
> use16
>}