На этом шаге мы рассмотрим организацию и использование макроопределений.
Общий вид макроопределения:
Имя MACRO параметры . . . . . ENDM
Определив блок один раз, можно использовать его в программе многократно. Причем в зависимости от значений параметров заменяемый участок может иметь разные значения. Если заданный участок предполагается многократно использовать, например в цикле, макроопределение имеет несомненные преимущества перед процедурой, т. к. несколько убыстряет выполнение кода. Пример:
EXC MACRO par1,par2 PUSH par1 POP par2 ENDM
Данное макроопределение приводит к обмену содержимым между параметрами: ЕХС ЕАХ,ЕВХ. Эквивалентно:
PUSH EAX POP EBX
Заметим, что если первый параметр будет непосредственно числом, то это приведет к загрузке данного числа во второй операнд.
Важным вопросом в связи с макроопределениями является проблема меток. Действительно, если мы будем применять в макроопределении обычные метки, то при использовании его более чем один раз возникнет коллизия. Коллизия эта разрешается при помощи объявления локальных меток. Для этого используется ключевое слово LOCAL. Например:
ЕХС MACRO par1,par2 LOCAL EXI CMP par1,par2 JE EXI PUSH par1 POP par2 EXI: ENDM
Данное макроопределение можно использовать сколь угодно много раз - при каждой подстановке ассемблер будет генерировать уникальную метку.
Для выхода из макроопределения (т. е. для прекращения генерации макроопределения) применяется директива EXITM. Она может понадобиться, если в макроопределении вы используете условные конструкции типа IF. .ENDIF.
На следующем шаге мы рассмотрим некоторые другие директивы.