|
|
|
|
Вложенные макросы
Рассмотренный нами макрос использует функцию DOS по записи символов на стандартное устройство вывода или в файл. Однако мы можем захотеть
проверить, была ли нажата клавиша для прерывания вывода, и если это не так, продолжить обработку. Функция DOS 0Bh проверяет, была ли нажата клавиша,
возвращая AL = 0FFh, если символ доступен, и AL = 00, если символ не доступен. Мы не можем написать макро chkchr и затем вызывать его из нашего
макроса WritToFil:
@ChkChr MACRO ;;определить макро @ChkChr
mov ah,0Bh ;;проверить стандартный ввод
int 21h ;;вызов DOS
ENDM ;;конец макро
;;
@WritToFil MACRO WAITFLAG,EKOFLAG ;; 2 аргумента
LOCAL bye ;;определить формальный адрес
IFNB ;;если поле для WAITFLAG не
;;пусто, ассемблировать
;;следующее
@ChkChr ;;выявить, ожидается ли символ
cmp al,0 ;; al = 0 => символ не ожидается
je bye ;;если символа нет, продолжить
ENDIF ;;конец проверки условия
IFIDN , ;;если EKOFLAG=EKO, ас-
;;семблировать
MOV AH,06H ;;функция DOS по записи
;;в стандартный вывод
ELSE ;;в противном случае
IFIDN <ЕKOFLAG>, ;;если EKOFLAG=NOEKO,
;;ассемблировать
MOV AH,40H ;;функция DOS по записи в файл
ELSE ;;если аргумент не соответствует
.ERR ;;выдать ошибку ассемблирования
ENDIF ;;конец проверки условия
int 21h ;;вызов DOS
bye:
ENDM ;;конец макро
|
Обсудим некоторые возможности новой версии WritToFil. Директива LOCAL сообщает MASM, что метка bye является формальной меткой,которую MASM заменяет
на реальную всякий раз, когда макро вызывается из программы. Это устраняет проблему использования одной и той же метки в программе дважды, что вызвало
бы ошибку ассемблирования. MASM ассемблирует макро, используя в первый раз метку ??0000, во второй раз - ??0001 и т.д. до ??FFFFh, что позволяет вызвать
макро в одной программе до 65536 раз. Директива LOCAL должна следовать сразу же за директивой MACRO - перед ней не может стоять даже комментарий!
Конструкция IFNB WAITFLAG сообщает MACRO о необходимости ассемблирования следующих трех строк только тогда, когда аргумент WAIT-FLAG не пуст. В противном
случае программный код включен не будет, и первой ассемблируемой строкой будет одна из строк блока IFIDN. Это предоставляет нам возможность генерации
программного кода, который или будет включаться в итоговую программу, или после проверки ключей будет опускаться. Оператор IFNB проверяет существование
WAITFLAG не по спеллингу, таким образом мы можем вызвать макро одной из следующих команд:
@WritToFil WAIT,EKO
@WritToFil WAITE,EKO
@WritToFil NoWate,EKO
@WritToFil FOOBAH,EKO
|
и затем генерировать код, который "не ждет" ввода. Заметим также, что мы получили вложенность макро, когда одно макро вызывает другое.
|
|