|
|
|
|
Сравнение строк. Пример
К сожалению, способность оператора .TYPE распознавать непосредственные операнды и регистры значительно уменьшается при выяснении типа операндов
макро. Так как особенно важно знать, является ли аргумент макро регистром, мы должны сконструировать способ выявления этого. Определение того,
является ли аргумент регистром, обычно полезно только вместе с неявным предположением, что если он не является регистром и не является определенной
адресной ссылкой, то предположительно является ссылкой на непосредственные данные.
Это хорошо сочетается с использованием условного ассемблирова ния на базе директив IRP и IRPC. Целью в данном случае является определение
принадлежности аргумента макро к какому-либо набору. Для решения задачи - является ли аргумент регистром, используется сопоставление строк. Так как
оператор .TYPE может определить только то, что эти регистры объявлены локально и абсолютны, для явной проверки имени регистра применяется макро
сопоставления строк. Эту функцию выполняет приведенное в Листинге 1-8 макро ?reg.
Листинг 1-8. Макро сопоставления имен регистров - ?reg
-----------------------------------------------------------------
FALSE EQU 0
TRUE EQU 0FFFFh
;;
;;**** ?REG - Определить, является ли аргумент регистром
;;
?reg MACRO arg
?isr8 = FALSE
?isr16 = FALSE
IRP reg,
IFIDN <&®>,<&arg>
?isr16 = TRUE
EXITM
ENDIF
ENDM ;; конец секции IRP
;; Если сравнились, остановиться здесь
IF (?isr16)
EXITM
ENDIF
;; Если еще не сравнились, продолжить далее
IRP reg,
IFIDN <&®>,<&arg>
?isr8 = TRUE
EXITM
ENDIF
ENDM ;; конец секции IRP
;; Если сравнились, остановиться здесь
IF (?isr8)
EXITM
ENDIF
;; Если не сравнились, попробовать прописные имена регистров
IRP reg,
IFIDN <&®>,<&arg>
?sir16 = TRUE
EXITM
ENDIF
ENDM ;; конец секции IRP
;; Если сравнились, остановиться здесь
IF (?isr16)
EXITM
ENDIF
;; Если еще не сравнились, попробовать еще
IRP reg,
IFIDN <&®>,<&arg>
?isr8 = TRUE
EXITM
ENDIF
ENDM ;; конец секции IRP
ENDM ;; конец макроописания
-----------------------------------------------------------------
|
Cердцевиной этого макро, как и любого макро сопоставления, являются команды:
IRP reg,
IFIDN <&®>,<&arg1>
?isr16 % TRUE
Интерпретировать эти строки можно так:
Для reg равного ax...ss выполнить . . .
Если reg равно аргументу arg . . .
Аргумент есть регистр!
|
Здесь следует остановиться на двух интересных моментах. Во-первых, необходимо явно проверять имена регистров, написанные как малыми, так и
большими буквами. Директива условного ассембли рования IFIDN сравнивает строки на точное соответствие. Несмотря на все усилия, макро ?reg не полно. Оно
не сопоставляет имена регистров, состоящие из одной большой и одной малой буквы (например "aL"). Во-вторых, необходимо проводить две проверки: одну
для 16-битовых регистров и одну для 8-битовых регистров. В данной реализации наличие двух отдельных проверок не приносит нам никакой выгоды, однако
такие проверки окажутся полезными в следующем примере.
Макро ?reg имеет два дополнительных синтаксических элемента. Один - директива завершения макро EXITM. Эта директива используется для завершения
работы макро ?reg при обнаружении совпадения.
Менее очевидно использование двойного амперсанда в операторе IFIDN. Согласно Руководству по MASM фирмы Майкрософт пользователь должен "указывать
столько амперсандов, сколько имеется уровней вложенности". Столь лаконичное выражение не вносит ясности в решение проблемы. "Уровни вложенности"
относятся не к глубине блоков, где появляется ссылка, а к глубине блоков, где находится ее описание. Таким образом, arg1 приводится только с одним
амперсандом, в то время как reg, описание которого находится во вложенном блоке, требует наличия двух амперсандов. Фирма Майкрософт не утверждает,
что это предел разрешенного количества уровней вложенности или количества требуемых амперсандов. В тех случаях, когда казалось бы необходимо указывать
множество амперсандов, попытки написания примеров, позволяющих выявить правильное функционирование, не увенчались успехом.
Приведенный Листинг 1-9 с макро ?reg показывает, что это макро выполняет возложенную на него функцию. Заметьте,что регистр bР, который распознается
MASM, отбрасывается макро ?reg. Это может быть истолковано, как необходимость соблюдения строгого правила ввода исходного текста программы с
клавиатуры.
Листинг 1-9. Тест макро сравнения имен регистров - ?reg
-----------------------------------------------------------------
?reg ax ; "AX" - регистр ?
FFFF dw ?isr16 <--- TRUE
?reg CS ; "CS" - регистр ?
FFFF dw ?isr16 <--- TRUE
?reg zork ; "ZORK" - регистр ?
0000 dw ?isr16 <--- FALSE
0000 dw ?isr8 <--- FALSE
?reg 01234h ; "1234" - регистр ?
0000 dw ?isr16 <--- FALSE
0000 dw ?isr8 <--- FALSE
?reg bР ; "BP" - регистр ?
0000 dw ?isr16 <--- FALSE
0000 dw ?isr8 <--- FALSE
-----------------------------------------------------------------
|
|
|