На главную Назад
Добро пожаловать, уважаемый посетитель!

В обработке макрокоманд применяется одно из ценных свойств

процедур: в генерацию макрокоманды можно вносить изменения с

помощью параметров. Точно так же, как параметры подпрограммы могут

влиять на ее выполнение, параметры макрокоманды определяют

фактически генерируемые команды. И так же, как и процедуры,

макрокоманды без параметров встречаются относительно редко.

 

Рассмотрим еще один простой пример. Мы составили программу так,

что во многих ее местах содержимое определенной ячейки памяти

складывается с различными константами. Вместо того, чтобы много раз

писать команду

 

ADD MEMORY_BYTE,5

или

ADD MEMORY_BYTE,7

 

 

нам хотелось бы воспользоваться для нее соответствующей

макрокомандой. Однако во всех приведенных командах константы

разные. Поэтому мы сделаем константу параметром макрокоманды. На

Фиг. 6.2 показаны определение и применение макрокоманды ADDBYTE. В

этом примере в качестве параметра в определении макрокоманды

используется символическое имя CONSTANT. Любые символичесике имена,

появляющиеся в поле операнда оператора MACRO, интерпретируются как

параметры. В момент определения макрокоманды у имени CONSTANT нет

никакого значения: оно просто резервирует место в тексте

макрокоманды. Позднее, при вызове и обработке текста макрокоманды,

вместо символического имени в определении макрокоманды

подставляется определенное значение параметра.

Важно отметить, что параметр макрокоманды - это текстовый

параметр. Так как макропроцессор фактически является текстовым

процессорорм, то он не отличает цифры от букв и наоборот. Это

позволяет при вызове макрокоманды использовать вместо чисел

символические имена. Любой смысл приписывается символьной строке не

макропроцессором, а ассемблером. Макропроцессор подставляет

Microsoft (R) Macro Assembler Version 5.001/1/80 04:02:43

Фиг. 6.2 Макрокоманда с аргументомPage1-1

 

 

PAGE,132

TITLEФиг. 6.2 Макрокоманда с аргументом

 

ADDBYTE MACROCONSTANT

ADDMEMORY_BYTE, CONSTANT

ENDM

 

0000CODESEGMENT

ASSUMECS:CODE

 

0000?? MEMORY_BYTEDB?

 

= 0004FOUREQU4 ; Симвользое изображение константы

 

ADDBYTE2

00012E: 80 06 0000 R 021ADDMEMORY_BYTE, 2

ADDBYTE4

00072E: 80 06 0000 R 041ADDMEMORY_BYTE, 4

ADDBYTEFOUR

000D2E: 80 06 0000 R 041ADDMEMORY_BYTE, FOUR

 

0013CODEENDS

END

 

Фиг. 6.2 Аргументы макрокоманды

 

текстовую строку из вызова макрокоманды на место символического

имени в определении макрокоманды. Таким образом программа может

использовать константное значение "FOUR" с тем же успехом, что и

константу "4".

 

Возможность использовать символические имена в качестве

параметров макрокоманд принципиально важна для следующего примера

макрокоманды. Этой макрокоманда, одной из команд сопроцессора 8087,

требуется параметр, который при обычном ее использовании почти

всегда бывает символическим именем. Макрокоманда FLDCW - это

команда сопроцессора 8087, которая задает ячейку памяти. Так как в

программах на языке ассемблера в большинстве случаев обращаются к

ячейкам памяти с помощью символических имен, то желательно

сохранить этот способ и для программирования сопроцессора 8087.

 

На Фиг.6.3 приводится макрокоманда FLDCW и несколько обрашений

к ней. Заметьте, что макрокоманда FLDCW использует в качестве

параметра символическое имя "SOURCE". Параметр SOURCE является

адресом, с которого сопроцессор 8087 загружает управляющее слово.

Для генерации требуемого машинного кода макрокоманда FLDCW

использует команду 8088 ESC. Однако для того, чтобы определить байт

mod=r/m команды, команде ESC требуется значение адреса. Как раз для

Microsoft (R) Macro Assembler Version 5.001/1/80 04:02:47

Фиг. 6.3 Макрокоманда для команды FLDCWPage1-1

 

 

PAGE,132

TITLEФиг. 6.3 Макрокоманда для команды FLDCW

 

FLDCWMACROSOURCE

DB09BH

ESC0DH, SOURCE

ENDM

 

0000CODESEGMENT

ASSUMECS:CODE

 

0000????MEMORY_LOCATION DW?

 

FLDCWMEMORY_LOCATION

00029B1DB09BH

00032E: D9 2E 0000 R1ESC0DH, MEMORY_LOCATION

FLDCWES:[DI]

00089B1DB09BH

000926: D9 2D 1ESC0DH, ES:[DI]

FLDCWMEMORY_LOCATION[BX+SI]

000C9B1DB09BH

000D2E: D9 A8 0000 R1ESC0DH, MEMORY_LOCATION[BX+SI]

 

0012CODEENDS

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

 

Вследующем примере вы увидите некоторые возможности множествен-

ности параметров.


 

Mail.ru