|
В противном случае прог-
раммный код включен не будет, и первой ассемблируемой строкой бу-
дет одна из строк блока IFIDN. Это предоставляет нам возможность
генерации программного кода, который или будет включаться в ито-
говую программу, или после проверки ключей будет опускаться. |
отказоустойчивые вычислительные системы |
|
|
Опе-
ратор IFNB проверяет существование WAITFLAG не по спеллингу, та-
ким образом мы можем вызвать макро одной из следующих команд:
@WritToFil WAIT,EKO
@WritToFil WAITE,EKO
@WritToFil NoWate,EKO
@WritToFil FOOBAH,EKO
и затем генерировать код, который "не ждет" ввода. Заметим также,
что мы получили вложенность макро, когда одно макро вызывает дру-
гое.
Несколько слов о возможностях макро
Вместо использования параметра WAITFLAG для определения, ас-
семблировать программный код для его включения или нет, мы также
можем использовать глобальную опцию, позволяющую осуществлять
этот выбор во время ассемблирования. |
dr web |
|
|
Например, мы хотим проверить
нажатие клавиши, если находимся в режиме отладки или если уста-
новлен параметр WAITFLAG, но ни при каких-либо других условиях.
Новое макроописание таково:
@WritToFil MAСRO WAITFLAG,EKOFLAG
LOCAL bye ;;определить формальный адрес
;;макро приема символа из стандартного ввода
;;2 аргумента: WAITFLAG и EKOFLAG определяют,
;;ждать символ или отобразить ввод
.ХCREF ;;подавить выдачу перекрестных ссылок
;;локальных меток и т.д.
x = 0 ;; х - индикатор
IFNDEF DEBUG ;;если параметр DEBUG не опре-
x = 1 ;;делен, установить флаг в 1
ENDIF ;;конец проверки условия
IFNB ;;если поле для WAITFLAG
x = 2 ;;не пусто, флаг = 2
ENDIF ;;конец проверки условия
IF (х EQ 1) or (x eq 2) ;;если не определен
;;DEBUG или не пуст WAITFLAG
@ChkChr ;;проверить, ожидается ли символ
cmp al,0 ;;al = 0 => символ не ожидается
je bye ;;если символа нет, продолжить
ENDIF ;;конец проверки условия
IFIDN , ;;если EKOFLAG = EKO,
- 1-54 -
;;ассемблировать следующую строку
mov ah,06h ;;функция DOS по записи в
;;стандартный вывод
ELSE ;;в противном случае
IFIDN , ;;если EKOFLAG=NOEKO,
;;ассемблировать
mov ah,40h ;;функция DOS по записи в файл
ELSE ;;если аргумент не соответствует
.ERR ;;выдать ошибку ассемблирования
%OUT Ошибка в макро @WritToFil - EKOFLAG не найден
ENDIF ;;конец проверки условия
ENDIF ;;конец проверки условия
int 21h ;;вызов DOS
bye:
.CREF ;;восстановить выдачу перекрестных ссылок
ЕNDМ ;;конец макро
Теперь во время ассемблирования для определения режима DEBUG
мы можем использовать опцию /d:
MASM myprgm,,,; /dDEBUG
и все вызовы макро WritToFil будут генерировать программный код,
проверяющий ввод.
Для определения, ждем ли мы появление символа, мы используем
флаг (с оператором =, а не equ, Так как мы переопределяем его в
следующих двух операторах IF). Вместо (x eq 1 ) или (x eq 2) мы
могли бы закодировать x gt 0 или x NE 0, тaк как действительно
любое значение, отличное от задаваемого при инициализации (0).
Заметим, что мы также добавили несколько новых директив. |
Отказоустойчивые системы |
|
|
резервное копирование данных, Навигационные системы, dr web, офисные программы, прокси сервера, .
система распознавания текста
|
Такая запись лишает нас
появления эха на экране, так как вместо EKO мы указали ECHO. Мы
можем исключить возможность появления такой ошибки, ограничив се-
бя использованием EKO или NOEKO:
@WritToFil MACRO EKOFLAG ;;определить INCHRIF c аргументом
;;EKOFLAG
IFIDN , ;;если EKOFLAG = EKO,
- 1-52 -
;;ассемблировать след-ую строку
mov ah,06h ;;функция DOS по записи в
;;стандартный файл
ELSE ;;в противном случае
IFIDN , ;;если EKOFLAG = NOEKO,
;;ассемблировать
mov ah,40h ;;функция DOS по записи в файл
ELSE ;;если аргумент не соответствует,
;; то
.ERR ;;выдать ошибку ассемблирования
ENDIF ;;конец проверки условия
int 21h ;; вызов DOS
ENDM ;; конец макро
Вложенные макросы
Рассмотренный нами макрос использует функцию 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 является формальной мет-
- 1-53 -
кой,которую MASM заменяет на реальную всякий раз, когда макро вы-
зывается из программы. Это устраняет проблему использования одной
и той же метки в программе дважды, что вызвало бы ошибку ассемб-
лирования. MASM ассемблирует макро, используя в первый раз метку
??0000, во второй раз - ??0001 и т.д. до ??FFFFh, что позволяет
вызвать макро в одной программе до 65536 раз. Директива LOCAL
должна следовать сразу же за директивой MACRO - перед ней не мо-
жет стоять даже комментарий! Конструкция IFNB WAITFLAG сообщает
MACRO о необходимости ассемблирования следующих трех строк только
тогда, когда аргумент WAIT-FLAG не пуст.
|
|
|