Макросредства ассемблера
Макрокоманды
Программы, написанные на языке ассемблера, часто содержат повторяющиеся участки текста с одинаковой структурой. Такой участок текста можно оформить в виде макроопределения, характеризующегося произвольным именем и необязательным списком формальных аргументов. После того, как такое определение сделано, появление в программе строки, содержащей имя макроопределения и список фактических аргументов (все это вместе называют макрокомандой), приводит к генерации всего требуемого текста, называемого макрорасширением. Варьируя фактические аргументы, можно, сохраняя неизменной структуру макрорасширения, изменить отдельные его элементы.
Макроопределение должно начинаться строкой с именем макроопределения и директивой macro, в поле аргументов которой указывается список формальных аргументов. Заканчивается макроопределение директивой endm.
Пусть в программе требуется неоднократно сохранять в стеке содержимое трех регистров, но в каждом конкретном случае номера регистров и их порядок отличаются. Оформим эти действия в виде макроопределения:
psh macroa,b,c push a push b push с endm
Появление в исходном тексте программы строки: psh АХ, ВХ, СХ приведет к генерации следующего фрагмента текста:
push AX push BX push CX
Если же в исходном тексте имеется строка: psh DX, ES, ВР то соответствующее макрорасширение будет иметь вид:
push DX push ES push BP
В качестве фактических аргументов могут выступать любые обозначения ассемблера, допустимые для данной команды. В частности, макровызов:
psh mem, [BX], ES: [17h]
Приведет к следующему макрорасширению:
push mem push [BX] push ES: [17h]
Если какие-то строки макроопределения должны быть помечены (например, с целью организации циклов), то обозначения меток следует объявить локальными с помощью оператора local. В этом случае ассемблер, генерируя макрорасширения, будет создавать собственные обозначения меток, не повторяющиеся при повторных вызовах одной и той же макрокоманды:
delay macro local point mov CX,200 point: loop point endm
Макрос delay создает задержку фиксированной длительности. Если в текст программы включить две макрокоманды delay:
… delay … delay
То их макрорасширения, подставленные в текст программы, будут выглядеть следующим образом:
… mov CX, 20000 ??0000: loop??0000 … mov CX, 20000 ??0000: loop??0000
При повторных подстановках макроопределения транслятор заменяет обозначение метки point на различающиеся обозначения ??0000, ??0001 и т.д., обеспечивая тем самым правильное выполнение команд циклов и переходов.