Попытка написать программу, в которой несколько раз используется макрокоманда вызова макроопределения, содержащего какой-нибудь оператор, имеющий метку, приведет к появлению сообщения об ошибке, т.к. имя упомянутой метки будет встречаться в тексте программы несколько раз. Для решения этой проблемы метки, встречающиеся в тексте макроопределения, должны быть описаны как локальные в директиве LOCAL, которая размещается сразу же за строкой заголовка макроопределения.
Метки, описанные как локальные, будут заменены на имена вида ??0000, в которых значение счетчика, начальное состояние которого показано четырьмя нулями, будет увеличиваться при каждой новой макроподстановке, макроопределений содержащих локальные метки.
В качестве примера рассмотрим макроопределение ABSAX, формирующее модуль целого числа, записанного в регистр ax.
ABSAX macro
local fin,met
cmp ax,8000h
je fin
met: neg ax
js met
fin: nop
endm
В результате макроподстановки из исходного текста:
mov ax,2
absax
mov ax, -5
absax
будет получено макрорасширение:
mov ax,2
absax
cmp ax,8000h
je ??0000
??0001: neg ax
js ??0001
??0000: nop
mov ax,-5
absax
cmp ax,8000h
je ??0002
??0003: neg ax
js ??0003
??0002: nop
Как правило тексты макроопределений хранятся в отдельном файле. Директива
INCLUDE path:\имя_файла
позволяет включить содержимое файла в состав теста программы. Конечно, в текст программы попадут все макроопределения, содержащиеся во включаемом файле. Некоторые из них, могут не понадобиться в данной программе. Директива PURGE позволяет сообщить макрогенератору имена макроопределений, которые не должны использоваться при компиляции данной программы. Директива PURGE только управляет работой компилятора, ни как не влияя на содержимое включаемого в текст программы файла.
Важным свойством макросов является возможность управлять процессом макрогенерации. Общий формат директив условной компиляции следующий:
IFxx условие
операторы
[ELSEIFxx
операторы
ELSE
операторы]
ENDIF
Директивы условной трансляции IFxx приведены в следующей таблице:
IF выражение |
Ассемблирование производится, если значение выражения истина. Возможно использование операторов отношения LT, GT, EQ, NE, LE, GE. |
IFE выражение |
Ассемблирование производится, если значение выражения ложь (ноль). |
IFB <аргумент> |
Ассемблирование производится, если значение аргумента пусто. Имя аргумента должно быть заключено в угловые скобки. |
IFNB <аргумент> |
Ассемблирование производится, если значение аргумента не пусто. Имя аргумента должно быть заключено в угловые скобки. |
IFIDN <арг1>,<арг2> |
Ассемблирование производится, если значения аргументов идентичны. Сравнение аргументов без различия регистров следует производить оператором IFIDNI. |
IFDIF <арг1>,<арг2> |
Ассемблирование производится, если значения аргументов различны. Сравнение аргументов без различия регистров следует производить оператором IFDIFI. |
IFDEF имя |
Ассемблирование производится, если имя было определено. |
IFNDEF имя |
Ассемблирование производится, если имя не было определено. |
С условными операторами часто используется директива EXITM – прекращения процесса макрогенерации текущего макроопределения.
Используя условные директивы можно организовать рекурсию:
pushall macro r1,r2,r3,r4,r5,r6,r7,r8
ifnb <r1>
push r1
pushall r2,r3,r4,r5,r6,r7,r8
endif
endm
Директивы повторения REPT, WHILE, IRP, IRPC позволяют избежать выписывания блока повторяющихся команд несколько раз. При этом эти директивы могут встречаться в любом месте программы, в том числе и внутри макроопределений. Блок повторяющихся команд, открытий одной из этих директив, должен заканчиваться директивой ENDM.
Директивы «REPT выражение» и «WHILE условие» удобны для формирования начальных значений различных таблиц. Например:
.data .data
k=0 k=4
REPT 5 WHILE k gt 1
db k db k
k =k+1 k=k-1
ENDM ENDM
Директивы «IRP параметр,<аргументы>» и «IRPC параметр, строка» дают возможность сформировать повторяющиеся команды с различными значениями параметра. При этом значением параметра в первой команде являются последовательности символов из списка аргументов, а во второй команде – каждый символ из строки. Например:
SaveReg macro RegList
irp reg,<RegList>
push reg
endm
endm
LoadReg macro List
irpс reg, List
pop reg&&x
endm
endm
Использование макрокоманд SaveReg <ax,bx,cx> и LoadRegcba приведет к появлению в тексте программы команд записывающих содержимое регистров ax, bx и cx в стек и команд, загружающих сохраненные значения в эти же регистры из стека.
Для облегчения поиска причин возникновения какой-либо нештатной ситуации служат директивы .ERRxx увеличивающие счетчик ошибок (символы xx см. в таблице на странице 2). К сожалению, эти директивы могут выводить на устройство вывода ошибок только код ошибки.
Текст сообщения об ошибке обнаруженной в процессе макрогенерации может быть выведен на стандартный вывод директивой %OUT текст илиDISPLAY “текст” .
Для досрочного прекращения процесса макрогенерации служит директива EXITM.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.