08 08 Возврат на шаг
09 09 Горизонтальная табуляция
10 0A Перевод строки
11 0B Вертикальная табуляция
12 0C Прогон страницы
13 0D Возврат каретки

Горизонтальная табуляция. Горизонтальная табуляция (шест.
09) возможна только на принтерах, имеющих соответствующее
обеспечение, иначе символы табуляции игнорируются. В
последнем случае можно имитировать табуляцию выводом
соответствующего числа пробелов.

Перевод строки. Символ перевода строки (шест.OA) исполь
зуется для прогона листа на один интервал. Соответственно
для печати через два интервала используется два символа
перевода строки.

Прогон страницы. Установка бумаги после включения принте
ра определяет начальную позицию печати страницы. Длина
страницы по умолчанию составляет 11 дюймов. Ни процессор, ни
принтер автоматически не определяют конец страницы. Если
ваша программа продолжает печатать после конца страницы,
то произойдет переход через межстраничную перфорацию на на
чало следующей страницы. Для управления страницами необходи
мо подсчитывать число напечатанных строк и при достижении
максимального значения (например, 55 строк) выдать код прого
на страницы (шест.OC) и, затем, сбросить счетчик строк в 0
или 1.
В конце печати необходимо выдать символ "перевода строки"
или "прогона страницы" для вывода на печать данные последней
строки, находящиеся в буфере печатающего устройства.
Использование последнего символа "прогон страницы" позволяет
установить напечатанный последний лист в положение для
отрыва.

ФУНКЦИИ ПЕЧАТИ В РАСШИРЕННОЙ ВЕРСИИ DOS
------------------------------------------------------------
В операционной системе DOS 2.0 имеются файловые
указатели, которые были показаны в главах по управлению
экраном дисплея и дисковой печати. Для вывода на печатающее
устройство используется функция DOS шест.40 и стандартный
файловый номер 04. Следующий пример демонстрирует печать 25
символов из области HEADG:

HEADG DB 'Industrial Bicycle Mfrs', 0DH, 0AH
...
MOV AH,40H ; Запрос печати
MOV BX,04 ; Файловый номер принтера
MOV CX,25 ; 25 символов
LEA DX,HEADG ; Область вывода
INT 21H ; Вызов DOS




Ассемблер для IBM PC. Глава 19 3


В случае ошибки операция устанавливает флаг CF и возвраща
ет код ошибки в регистре AX.

ПРОГРАММА: ПОСТРАНИЧНАЯ ПЕЧАТЬ С ЗАГОЛОВКАМИ
------------------------------------------------------------
Программа, приведенная на рис.19.1, аналогична программе
на рис.9.1, за исключением того, что после ввода имен с
клавиатуры выводит их не на экран, а на печатающее устрой
ство. Каждая напечатанная страница содержит заголовок и
через двойной интервал список введенных имен в следующем
виде:

List of Employee Names Page 01
Clancy Alderson
Ianet Brown
David Christie
...

Программа подсчитывает число напечатанных строк и при дос
тижении конца страницы выполняет прогон до начала следующей
страницы. В программе имеются процедуры:

D10INPT Выдает на экран запрос и затем вводит имя с кла
виатуры.
E10PRNT Выводит имя на печатающее устройство (длина име
ни берется из вводного списка параметров); в
конце страницы вызывает процедуру M10PAGE.
M10PAGE Выполняет прогон на новую страницу, печатает за
головок, сбрасывает счетчик строк и увели чивает
счетчик страниц на единицу.
P100UT Общая подпрограмма для непосредственного вывода
на печатающее устройство.

В начале выполнения необходимо напечатать заголовок, но
не делать перед этим перевод страницы. Поэтому процедура
M10PAGE обходит перевод страницы, если счетчик PAGECTR
содержит 01 (начальное значение). Поле PAGECTR определено
как
PAGECTR DB '01'

В начале выполнения необходимо напечатать заголовок, но
не делать перед этим перевод страницы. Поэтому процедура
M10PAGE обходит перевод страницы, если счетчик PAGECTR
содержит 01 (начальное значение). Поле PAGECTR определено
как
PAGECTR DB '01'

В результате будет сгенерировано число в ASCII коде - шест.
3031. Процедура M10PAGE увеличивает счетчик PAGECTR на 1
так, что значение становится последовательно 3032, 3033 и
т.д. Эти значения корректны до 3039, далее следует 303A, что
будет распечатано, как двоеточие (:). Поэтому, если в правом
байте поля PAGECTR появляется шест.3A, то это значение



Ассемблер для IBM PC. Глава 19 4


заменяется на шест.30, а к левому байту прибавляется
единица. Таким образом шест.303A перекодируется в шест.
3130, т.е. в 10 в символьном представлении.

------------------------------------------------------------
------------------------------------------------------------
Рис.19.1. Постраничная печать с заголовком.

Проверка на конец страницы до (но не после) печати имени
гарантирует, что на последней странице будет напечатано по
крайней мере одно имя под заголовком.

ПЕЧАТЬ ASCII-ФАЙЛОВ И ТАБУЛЯЦИЯ
------------------------------------------------------------

Табуляция, обеспечиваемая, например, видеоадаптерами,
заключается в замене одного символа табуляции (код 09)
несколькими пробелами при выводе так, чтобы следующая
позиция была кратна 8. Таким образом, стандартные позиции
табуляции являются 8, 16, 24 и т.д. Многие принтеры, однако,
игнорируют символы табуляции. Поэтому, такая программа, как
DOS PRINT, предназначенная для печати ASCII файлов (например
ассемблерных исходных текстов) проверяет каждый символ,
посылаемый на принтер. И, если обнаруживается символ
табуляции, то программа выдает несколько пробелов до позиции
кратной 8.
Программа, приведенная на рис.19.2, выводит на экран
запрос на ввод имени файла и, затем, печатает содержимое
указанного файла. Эта программа в отличие от приведенной на
рис.17.3 (вывод файлов на экран) осуществляет замену
выводимых символов табуляции на соответствующее число
пробелов. В результате символ табуляции в позициях от 0 до 7
приводит к переходу на позицию 8, от 8 до 15 - на 16 и т.д.
Команды, реализующие данную логику, находятся в процедуре
G10XFER после метки G60. Рассмотрим три примера обработки
символа табуляции:

Текущая позиция печати: 1 9 21
Двоичное значение: 00000001 00001001 00010101
Очистка трех правых битов: 00000000 00001000 00010000
Прибавление 8: 00001000 00010000 00011000
Новая позиция: 8 16 24

В программе организованы следующие процедуры:

С10PRMP Запрашивает ввод имени файла. Нажатие только
клавиши Return приводит к завершению работы
программы.
E10OPEN Открывает дисковый файл по указанному имени.
G10XFER Контролирует конец сектора, конец файла, конец
области вывода, символы "перевод строки" и табуля
ции. Пересылает обычные символы в область вывода.




Ассемблер для IBM PC. Глава 19 5


P10PRNT Распечатывает выводную строку и очищает область
вывода.
R10READ Считывает сектор из дискового файла.

Коды "возврат каретки", "перевод строки" и "прогон
страницы" действительны для любых принтеров. Можно модифици
ровать программу для подсчета распечатываемых строк и
выполнения прогона страницы (шест.OC) при достижении,
например, строки 62.

------------------------------------------------------------
------------------------------------------------------------
Рис.19.2. Печать ASCII файла.

Некоторые пользователи предпочитают устанавливать символы
"прогон страницы" в ASCII файлах с помощью текстового
редактора в конкретных местах текста, например, в конце
ассемблерных процедур. Кроме того, можно изменить программу
для функции 05 базовой версии DOS. Эта функция выполняет
вывод каждого символа непосредственно на принтер. Таким
образом можно исключить определение и использование области
вывода.

ПЕЧАТЬ ПОД УПРАВЛЕНИЕМ БАЗОВОЙ DOS
------------------------------------------------------------

Для печати в базовой версии DOS необходимо установить в
регистре AH код функции 05, а в регистр DL поместить
распечатываемый символ и, затем, выполнить команду INT 21H
следующим образом:

MOV AH,05 ;Запрос функции печати
MOV DL,char ;Распечатываемый символ
INT 21H ;Вызов DOS

С помощью этих команд можно передавать на принтер
управляющие символы. Однако, печать, обычно, предполагает
вывод полной или частичной строки текста и пошаговую
обработку области данных, отформатированной по строкам.
Ниже показазна программа печати полной строки. Сначала в
регистр SI загружается начальный адрес области HEADG, а в
регистр CX - длина этой области. Цикл, начинающийся по метке
P20, выделяет очередной символ из области HEADG и посылает
его на принтер. Так как первый символ области HEADG -
"прогон страницы", а последние два - "перевод строки", то
заголовок печатается в начале новой страницы и после него
следует двойной интервал.

HEADG DB 0CH,'Industrial Bicycle Mfrs',0DH,0AH,0AH
LEA SI,HEADG ;Установка адреса и
MOV CX,27 ; длины заголовка
P20:
MOV AH,05 ;Запрос функции печати



Ассемблер для IBM PC. Глава 19 6


MOV DL,[SI] ;Символ из заголовка
INT 21H ;Вызов DOS
INC SI ;Следующий символ
LOOP P20

Пока принтер не включен, DOS выдает сообщения "Out of pap
er". После включения питания программа начинает работать
нормально. Для прекращения печати можно нажать клавиши
Ctrl/Break.

СПЕЦИАЛЬНЫЕ КОМАНДЫ ПРИНТЕРА
------------------------------------------------------------

Выше уже был показан ряд команд, которые являются
основными для большинства печатающих устройств. Кроме того
существуют следующие команды:

Десятичн. Шест.
15 0F Включить узкий формат
14 0E Включить широкий формат
18 12 Выключить узкий формат
20 14 Выключить широкий формат

Есть команды, которые распознаются по предшествующему
символу Esc (шест.IB). Некоторые из них в зависимости от
печатающего устройства представлены ниже:

1B 30 Установить плотность 8 строк на дюйм
1B 32 Установить плотность 6 строк на дюйм
1B 45 Включить жирный формат
1B 46 Выключить жирный формат

Коды команд можно посылать на принтер двумя разными
способами:

1. Определить команды в области данных. Следующий пример
устанавливает узкий формат, 8 строк на дюйм, затем
печатает заголовок с завершающими командами "возврат
каретки" и " перевод строки":

HEADG DB 0FH, 1BH, 30H, 'Title...', 0DH, 0AH

2. Использовать команды с непосредственными данными:

MOV AH,05 ;Запрос функции печати
MOV DL,0FH ;Включить узкий формат
INT 21H

Все последующие символы будут печататься в узком
формате до тех пор, пока программа не выдаст на принтер
команду, выключающую этот формат.





Ассемблер для IBM PC. Глава 19 7


Приведенные команды не обязательно работают на принтерах
любых моделей. Для проверки возможных команд управления
следует ознакомиться с руководством конкретного печатающего
устройства.

ПЕЧАТЬ С ПОМОЩЬЮ BIOS INT 17H
------------------------------------------------------------

Прерывание BIOS INT 17H обеспечивает три различные
операции, специфицированные содержимым регистра AH:

AH=0: Данная операция выполняет печать одного символа на
три принтера по номерам 0,1 и 2 (стандартное значение - 0).

MOV AH,00 ;Запрос функции печати
MOV AL,char ;Символ, выводимый на печать
MOV DX,00 ;Выбор принтера Э 0
INT 17H ;Вызов BIOS

Если операция не может распечатать символ, то в регистре AH
устанавливается значение 01.

AH=1: Инициализация порта печатающего устройства:

MOV AH,01 ;Запрос на инициализацию порта
MOV DX,00 ;Выбор порта Э 0
INT 17H ;Вызов BIOS

Данная операция посылает на принтер символ "прогон
страницы", поэтому ее можно использовать для установки
положения "верх страницы". Большинство принтеров выполняют
данную установку автоматически при включении.

AH=2: Чтение состояние порта принтера:

MOV AH,02 ;Функция чтения состояния порта
MOV DX,00 ;Выбор порта Э 0
INT 17H ;Вызов BIOS
TEST AH,00101001B; Принтер готов?
JNZ errormsg ;Нет - выдать сообщение об ошибке

Назначение функций AH=1 и AH=2 состоит в определении
состояния принтера. В результате выполнения этих функций
биты регистра AH могут устанавливаться в 1:

Бит Причина
7 Не занято
6 Подтверждение от принтера
5 Конец бумаги
4 Выбран
3 Ошибка ввода/вывода
0 Таймаут




Ассемблер для IBM PC. Глава 19 8


Если прринтер включен, то операция возвращает шест.90 или
двоичное 10010000 - принтер "не занят" и "выбран" - это
нормальное состояние готовности. В случае неготовности
принтера устанавливаются бит 5 (конец бумаги или бит 3
(ошибка вывода). Если принтер выключен, то операция
возвращает шест.B0 или двоичное 10110000, указывая на "конец
бумаги".
Выполняя программу при выключенном принтере, BIOS не
выдает сообщение автоматически, поэтому предполагается, что
программа должна сама проверить и отреагировать на состояние
принтера. Если программа не делает этого, то единственной
индикацией будет мигающий курсор на экране дисплея. Если в
этот момент включить принтер, то некоторые выходные данные
могут быть потеряны. Следовательно, прежде чем использовать
функции BIOS для печати, следует проверить состояние порта
принтера и, если будет обнаружена ошибка, то выдать
соответствующее сообщение. (Функции DOS выполняют эту
проверку автоматически, хотя их сообщение "Out of paper"
относится к различным состояниям). После включения принтера,
вывод сообщений об ошибке прекращается и принтер начинает
нормально работать без потери данных.
В процессе работы принтер может выйти за страницу или
быть нечаянно выключен. Поэтому в программах печати следует
предусмотреть проверку состояния принтера перед каждой
попыткой печати.

ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
------------------------------------------------------------

ъ Прежде чем выводить данные на печатающее устройство,
включите принтер и вставьте в него бумагу.

ъ Для завершении печати используйте символы "перевод
строки" и "прогон страницы" для очистки буфера
принтера.

ъ Функции DOS для печати предусматривают вывод сообщений
при возникновении ошибки принтера. Функции BIOS
возвращают только код состояния. При использовании BIOS
INT 17H проверяйте состояние принтера перед печатью.

ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
------------------------------------------------------------

19.1. Напишите программу в расширенной версии DOS для а)
прогона страницы; б) печати вашего имени; в) перевода
строки и печати вашего адреса; г) перевода строки и
печати названия вашего города/штата (республики); д)
прогона страницы.
19.2. Переделайте программу из предыдущего вопроса для
базовой версии DOS.





Ассемблер для IBM PC. Глава 19 9


19.3. Закодируйте строку, в которой имеется следующая
информация: возврат каретки, прогон страницы, включе
ние узких букв, заголовок (любое имя) и выключение
узких букв.
19.4. Измените программу из вопроса 19.1 для использования
BIOS INT 17H. Обеспечьте проверку состояния
принтера.
19.5. Измените программу из вопроса 19.1 так, чтобы пункты
б), в), г) выполнялись по 5 раз.
19.6. Измените программу на рис.19.1 для выполнения в
базовой версии DOS.
19.7. Измените программу на рис.19.2 так, чтобы распечатывае
мые строки также выводились на экран.











































Ассемблер для IBM PC. Глава 20 18



    ГЛАВА 20. Макросредства


------------------------------------------------------------

Макросредства

Цель: Объяснить определение и использование ассемблерных
макрокоманд.

ВВЕДЕНИЕ
------------------------------------------------------------

Для каждой закодированной команды ассемблер генерирует
одну команду на машинном языке. Но для каждого
закодированного оператора компиляторного языка Pascal или C
генерируется один или более (чаще много) команд машинного
языка. В этом отношении можно считать, что компиляторный
язык состоит из макро операторов.
Ассемблер MASM также имеет макросредства, но макросы
здесь определяются программистом. Для этого задается имя
макроса, директива MACRO, различные ассемблерные команды,
которые должен генерировать данный макрос и для завершения
макропределения - директива MEND. Затем в любом месте
программы, где необходимо выполнение определенных в макроко
манде команд, достаточно закодировать имя макроса. В резуль
тате ассемблер сгенерирует необходимые команды.

Использование макрокоманд позволяет:
- упростить и сократить исходный текст программы;
- сделать программу более понятной;
- уменьшить число возможных ошибок кодирования.

Примерами макрокоманд могут быть операции ввода-вывода,
связанные с инициализацией регистров и выполнения прерываний
преобразования ASCII и двоичного форматов данных, арифмети
ческие операции над длинными полями, обработка строковых
данных, деление с помощью вычитания.
В данной главе рассмотрены особенности макросредств,
включая те, которые не достаточно ясно даны в руководстве по
ассемблеру. Тем не менее пояснения для некоторых малоисполь
зуемых операций следует искать в руководстве по ассеблеру.

ПРОСТОЕ МАКРООПРЕДЕЛЕНИЕ
------------------------------------------------------------

Макроопределение должно находиться до определения
сегмента. Рассмотрим пример простого макроопределения по
имени INIT1, которое инициализирует сегментные регистры для
EXE-программы:

INIT1 MACRO ;Начало
ASSUME CS:CSEG,DS:DSEG,SS:STACK;ES:DSEG ; \
PUSH DS ; \



Ассемблер для IBM PC. Глава 20 19


SUB AX,AX ; \
PUSH AX ;Тело \
MOV AX,DSEG ;макро/
MOV DS,AX ; /
MOV ES,AX ; /
ENDM ;Конец

Директива MACRO указывает ассемблеру, что следующие
команды до директивы ENDM являются частью макроопределения.
Имя маккрокоманды - INIT1, хотя здесь возможны другие
правильные уникальные ассемблерные имена. Директива ENDM
завершает макроопределение. Семь команд между директивами
MACRO и ENDM составляют тело макроопределения.
Имена, на которые имеются ссылки в макроопределении,
CSEG, DSEG и STACK должны быть определены где-нибудь в
другом месте программы. Макрокоманда INIT1 может использо
ваться в кодовом сегменте там, где необходимо инициализиро
вать регистры. Когда ассемблер анализирует команду INIT1,
он сначала просматривает таблицу мнемокодов и, не обнаружив
там соответствующего элемента, проверяет макрокоманды. Так
как программа содержит определение макрокоманды INIT1 ассем
блер подставляет тело макроопределения, генерируя необходи
мые команды - макрорасширение. Программа использует
рассматриваемую макрокоманду только один раз, хотя имеются
другие макрокоманды, предназначенные на любое число
применений и для таких макрокоманд ассемблер генерирует
одинаковые макрорасширения.
На рис.20.1 показана ассемблированная программа. В листин
ге макрорасширения каждая команда, помеченная слева знаком
плюс (+), является результатом генерации макрокоманды. Кроме
того, в макрорасширении отсутствует директива ASSUME, так
как она не генерирует объектный код.
В последующем разделе "Включение из библиотеки макро
определений показана возможность каталогизации макрокоманд в
библиотеке и автоматическое включение их в любые программы.

------------------------------------------------------------
------------------------------------------------------------
Рис.20.1. Пример ассемблирования макрокоманды.

ИСПОЛЬЗОВАНИЕ ПАРАМЕТРОВ В МАКРОКОМАНДАХ
------------------------------------------------------------

В предыдущем макроопределении требовались фиксированные
имена сегментов: CSEG, DSEG и STACK. Для того, чтобы макро
команда была более гибкой и могла принимать любые имена
сегментов, определим эти имена, как формальные параметры:

INIT2 MACRO CSNAME,DSNAME,SSNAME ;Формальные параметры
ASSUME CS:CSNAME,DS:DSNAME,SC:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX



Ассемблер для IBM PC. Глава 20 20


MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM ;Конец макроопределения

Формальные параметры в макроопределении указывают
ассемблеру на соответствие их имен любым аналогичным именам
в теле макроопределения. Все три формальных параметра
CSNAME, DSNAME и SSNAME встречаются в директиве ASSUME, а
параметр DSNAME еще и в последующей команде MOV. Формальные
параметры могут иметь любые правильные ассемблерные имена,
не обязательно совпадающими именами в сегменте данных.
Теперь при использовании макрокоманды INIT2 необходимо
указать в качестве параметров действительные имена трех
сегментов в соответствующей последовательности. Например,
следующая макрокоманда содержит три параметра, которые
соответствуют формальным параметрам в исходном макроопреде
лении:

Макроопределение:
INIT2 MACRO CSNAME,DSNAME,SSNAME (формальные параметры)
Макрокоманда: | | |
INIT2 CSEG,DSEG,STACK (параметры)

Так как ассемблер уже определил соответствие между формальны
ми параметрами и операторами в макроопределении, то теперь
ему остается подставить параметры макрокоманды в макрорасши
рении:

- Параметр 1: CSEG ставится в соответствие с CSNAME в
макроопределении. Ассемблер подставляет CSEG вместо
CSNAME в директиве ASSUME.

- Параметр 2: DSEG ставится в соответствие с DSNAME в
макроопределении. Ассемблер подставляет DSEG вместо
двух DSNAME: в директиве ASSUME и в команде MOV.

- Параметр 3: STACK ставится в соответствие с SSNAME в
макроопределении. Ассемблер подставляет STACK вместо
SSNAME в директиве ASSUME.

Макроопределение с формальными параметрами и соответствую
щее макрорасширение приведены на рис.20.2.

------------------------------------------------------------
------------------------------------------------------------
Рис.20.2. Использование параметров в макрокомандах.

Формальный параметр может иметь любое правильное
ассемблерное имя (включая имя регистра, например, CX),
которое в процессе ассемблирования будет заменено на
параметр макрокоманды. Отсюда следует, что ассемблер не
распознает регистровые имена и имена, определенные в области



Ассемблер для IBM PC. Глава 20 21


данных, как таковые. В одной макрокоманде может быть
определено любое число формальных парамтеров, разделенных
запятыми, вплоть до 120 колонки в строке.

КОММЕНТАРИИ
------------------------------------------------------------

Для пояснений назначения макроопределения в нем могут
находиться комментарии. Директива COMMENT или символ точка с
запятой указывают на строку комментария, как это показано в
следующем макроопределении PROMPT:

PROMPT MACRO MESSGE
; Эта макрокоманда выводит сообщения на экран
MOV AH,09H
LEA DX,MESSGE
INT 21H
ENDM

Так как по умолчанию в листинг попадают только команды
генерирующие объектный код, то ассемблер не будет автомати
чески выдавать и комментарии, имеющиеся в макроопределении.
Если необходимо, чтобы в расширении появлялись комментарии,
следует использовать перед макрокомандой директиву .LALL
("list all" - выводить все), которая кодируется вместе с
лидирующей точкой:
.LALL
PROMPT MESSAG1

Макроопределение может содержать несколько комментариев,
причем некоторые из них могут выдаваться в листинге, а
другие - нет. В первом случае необходимо использовать
директиву .LALL. Во втором - кодировать перед комментарием
два символа точка с запятой (;;) - признак подавления вывода
комментария в листинг. По умолчанию в ассемблере действует
директива .XALL, которая выводит в листинг только команды,
генерирующие объектный код. И, наконец, можно запретить
появление в листинге ассемблерного кода в макрорасширениях,
особенно при использовании макрокоманды в одной программе
несколько раз. Для этого служит директива .SALL ("suppress
all" - подавить весь вывод), которая уменьшает размер
выводимого листинга, но не оказывает никакого влияния на
размер объектного модуля.
Директивы управления листинком .LALL, .XALL, .SALL
сохраняют свое действие по всему тексту программы, пока
другая директива листинга не изменит его. Эти директивы
можно размещать в программе так, чтобы в одних макрокомандах
распечатывались комментарии, в других - макрорасширения, а в
третьих подавлялся вывод в листинг.
Программа на рис.20.3 демонстрирует описанное выше
свойство директив листинга. В программе опредлелено два
макроопределения INIT2 и PROMPT, расмотренные ранее. Кодовый
сегмент содержит директиву .SALL для подавления распечатки



Ассемблер для IBM PC. Глава 20 22


INIT2 и первого расширения PROMPT. Для второго расширения
PROMPT директива .LALL указывает ассемблеру на вывод в
листинг комментария и макрорасширения. Заметим, однако, что
комментарий, отмеченный двумя символами точка с запятой (;;)
в макроопределении PROMPT, не распечатывается в макрорасшире
ниях независимо от действия директив управления листингом.

------------------------------------------------------------
------------------------------------------------------------
Рис.20.3. Распечатка и подавление макрорасширений
в листинге.

ИСПОЛЬЗОВАНИЕ МАКРОКОМАНД В МАКРООПРЕДЕЛЕНИЯХ
------------------------------------------------------------

Макроопределение может содержать ссылку на другое
макроопределение. Рассмотрим простое макроопределение DOS21,
которое заносит в регистр AH номер функции DOS и выполняет
INT 21H:

DOS21 MACRO DOSFUNC
MOV AH,DOSFUNC
INT 21H
ENDM

Для использования данной макрокоманды при вводе с клавиатуры
необходимо закодировать:

LEA DX,NAMEPAR
DOS21 0AH

Предположим, что имеется другое макроопределение, использую
щее функцию 02 в регистре AH для вывода символа:

DISP MACRO CHAR
MOV AH,02
MOV DL,CHAR
INT 21H
ENDM

Для вывода на экран, например, звездочки достаточно закодиро
вать макрокоманду DISP '*'. Можно изменить макроопределение
DISP, воспользовшись макрокомандой DOC21:

DISP MACRO CHAR
MOV DL,CHAR
DOS21 02
ENDM

Теперь, если закодировать макрокоманду DISP в виде DISP '*',
то ассемблер сгенерирует следующие команды: