В обработке макрокоманд применяется одно из ценных свойств процедур: в генерацию макрокоманды можно вносить изменения с помощью параметров. Точно так же, как параметры подпрограммы могут влиять на ее выполнение, параметры макрокоманды определяют фактически генерируемые команды. И так же, как и процедуры, макрокоманды без параметров встречаются относительно редко.
Рассмотрим еще один простой пример. Мы составили программу так, что во многих ее местах содержимое определенной ячейки памяти складывается с различными константами. Вместо того, чтобы много раз писать командуADD MEMORY_BYTE,5
или
ADD MEMORY_BYTE,7
Фиг. 6.2 Макрокоманда с аргументом Page 1-1
PAGE ,132
TITLE Фиг. 6.2 Макрокоманда с аргументом
ADDBYTE MACRO CONSTANT
ADD MEMORY_BYTE, CONSTANT
ENDM
0000 CODE SEGMENT
ASSUME CS:CODE
0000 ?? MEMORY_BYTE DB ?
= 0004 FOUR EQU 4 ; Симвользое изображение константы
ADDBYTE 2
0001 2E: 80 06 0000 R 02 1 ADD MEMORY_BYTE, 2
ADDBYTE 4
0007 2E: 80 06 0000 R 04 1 ADD MEMORY_BYTE, 4
ADDBYTE FOUR
000D 2E: 80 06 0000 R 04 1 ADD MEMORY_BYTE, FOUR
0013 CODE ENDS
END
Фиг. 6.2 Аргументы макрокоманды
текстовую строку из вызова макрокоманды на место символического имени в определении макрокоманды. Таким образом программа может использовать константное значение "FOUR" с тем же успехом, что и константу "4".
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:02:47
Фиг. 6.3 Макрокоманда для команды FLDCW Page 1-1
PAGE ,132
TITLE Фиг. 6.3 Макрокоманда для команды FLDCW
FLDCW MACRO SOURCE
DB 09BH
ESC 0DH, SOURCE
ENDM
0000 CODE SEGMENT
ASSUME CS:CODE
0000 ???? MEMORY_LOCATION DW ?
FLDCW MEMORY_LOCATION
0002 9B 1 DB 09BH
0003 2E: D9 2E 0000 R 1 ESC 0DH, MEMORY_LOCATION
FLDCW ES:[DI]
0008 9B 1 DB 09BH
0009 26: D9 2D 1 ESC 0DH, ES:[DI]
FLDCW MEMORY_LOCATION[BX+SI]
000C 9B 1 DB 09BH
000D 2E: D9 A8 0000 R 1 ESC 0DH, MEMORY_LOCATION[BX+SI]
0012 CODE ENDS
END
Фиг. 6.3. Макрокомнда FLDCW
этого макрокоманда и использует параметр SOURCE. Такая организация макрокоманды FLDCW позволяет программировать весьма естественным способом. Точно так же как пишетсяINC MEMORY_LOCATION
вы можно написать команду для сопроцессора 8087
FLDCW MEMORY_LOCATION
Это справедливо не только для адресов, заданных символическими именами, но и для других способов адресации. На Фиг. 6.3 показано несколько примеров задания операнда с помощью адресации по базе и индексу. Так как макропроцессор воспринимает параметр как какой-то фрагмент текста, то параметр может быть образован любой символьной строкой, какую вы пожелаете.
Можно задать макрокоманду и с несколькими параметрами. Единственное, что ограничивает число параметров макрокоманды, это длина ассемблерной строки. Все, что следует за оператором MACRO интерпретируется макропроцессором как параметр. Для разделения символических имен в определении макрокоманды пользуются запятыми. Оператор MACRO с тремя параметрами будет выглядеть следующим образом:
EXAMPLE MACRO ARG1, ARG2, ARG3
Аналогично, при вызове макрокоманды вы должны задать значение каждого из параметров. Если вы хотите пропустить какой-то параметр, то ассемблер подставит вместо него символьную строку нулевой длины. Иногда это полезно, но часто приводит к неправильной трансляции. Если макрокоманда имеет более одного параметра, то при вызове макрокоманды относящийся к параметрам текст разделяется запятыми. Это в точности совпадает со способом задания нескольких параметров к любой из команд микропроцессора 8088, поэтому будет вполне естественным для вас. Вызов макрокоманды с тремя параметрами может выглядеть так:
EXAMPLE 5, [BX], MEMORY_BYTE
В следующем примере вы увидите некоторые возможности множественности параметров.