macro message arg
{
if arg eqtype ""
local str
jmp @f
str db arg,0Dh,0Ah,24h
@@:
mov dx,str
else
mov dx,arg
end if
mov ah,9
int 21h
}
Вышеописанный макрос создан для показа сообщений в программах DOS. Если аргумент этого макроса некоторое число, метка или переменная, показывается строка из этого адреса, но если аргумент — это строка в кавычках, то созданный код покажет её после … и … .
Также возможно объявить макроинструкцию внутри другой макроинструкции, то есть один макрос может определить другой, но с такими определениями есть проблема, вызванная тем, что знак « }
» не может появляться внутри макроинструкции, он всегда означает конец его определения. Чтобы обойти эту проблему, можно избавиться от мешающих символов. Это делается путем подстановки одного или больше обратных слэшей перед любыми другими символами (даже специальными знаками). Препроцессор видит эту последовательность как один символ, но каждый раз, когда он видит такой символ во время обработки макроса, он обрезает обратные слэши с его начала. Например, « \{
» трактуется как один символ, но во время обработки макроса он станет символом « \{
». Это позволит вам определить одну макроинструкцию внутри другой:
macro ext instr
{
macro instr op1,op2,op3
\{
if op3 eq
instr op1,op2
else
instr op1,op2
instr op2,op3
end if
\}
}
ext add
ext sub
Макрос « ext
» определен корректно, но когда он используется, символы « \{
» и « \}
» становятся « {
» и « }
». То есть когда обрабатывается « ext add
», содержание макроса становится действительным определением макроинструкции, и таким образом определяется макрос « add
». Так же « ext sub
» определяет макрос « sub
». Использование символа « \{
» не было здесь действительно необходимо, но сделано таким образом для того, чтобы определение было более ясным.
Если некоторые директивы, специфические для макроинструкций, такие как « local
» или « common
», требуются в некотором макросе, включенном таким образом, то их можно избежать таким же путем. Исключение символа больше чем одним обратным слэшем так же поддерживается, это позволяет допустить множественные уровни вложения определений макросов.
Другая техника определения макроинструкций внутри других состоит в использовании директивы « fix
», которая становится полезной, когда некоторый макрос только начинает определение другого, без его закрытия. Например:
macro tmacro params
{
macro params {
}
MACRO fix tmacro
ENDM fix }
определяет альтернативный синтаксис определения макросов, который выглядит как:
MACRO stoschar char
mov al,char
stosb
ENDM
Имейте в виду, что таким образом заданное определение должно быть создано с применением директивы « fix
», так как перед тем, как процессор ищет знак « }
» во время определения макроса, обрабатываются только символьные константы высшего приоритета! Может возникнуть проблема, если требуется выполнить некоторые дополнительные задания в конце такого определения, но есть еще одно свойство, которое в таких случаях поможет вам. А именно возможно поместить любую директиву, инструкцию или макроинструкцию сразу после символа « }
», который заканчивает макроинструкцию и она будет обработана так же, как если бы была на следующей строке.
« struc
» — это специальный вариант директивы « macro
», который используется для определения структур данных. Макроинструкции, определенные директивой « struc
», когда используются, должны предваряться меткой (как директивы определения данных). Эта метка будет также присоединена к началу каждого имени, начинающегося с точки, в содержании макроинструкции. Макроинструкция, определенная с использованием директивы « struc
», может иметь такое же имя, как макросы, определенные с использованием директивы « macro
». Структурная макроинструкция не будет мешать обычному макросу, выполняющемуся без метки перед ним и наоборот. Все правила и свойства, касающиеся стандартных макросов, применимы к структурным макроинструкциям.
Вот пример структуры:
struc point x,y
{
.x dw x
.y dw y
Читать дальше