- •Глава 14
- •Макрокоманды
- •Макродирективы
- •Директивы while и rept
- •Директива irp
- •Директива irpc
- •Директивы условной компиляции
- •Директивы компиляции по условию
- •Директивы if и ife
- •Директивы ifdef и ifndef
- •Директивы ifb и ifnb
- •Директивы ifidn, ifidni, ifdif и ifdifi
- •Вложенность директив условной трансляции
- •Директивы генерации ошибок
- •Безусловная генерация пользовательской ошибки
- •Условная генерация пользовательской ошибки
- •Директивы .Errb (errifb) и .Errnb (errifnb)
- •Директивы .Errdef (errifdef) и .Errndef (errifndef)
- •Директивы .Errdif (errifdif) и .Erridn (errifidn)
- •Директивы .Erre (errife) и .Errnz (errif)
- •Константные выражения в условных директивах
- •Дополнительные средства управления трансляцией
- •Директивы управления файлом листинга
Директивы if и ife
Синтаксис директив IF и IFE следующий:
IF(E) логическое_выражение
фрагмент_программы_1
ELSE
фрагмент_программы_2
ENDIF
Обработка этих директив макроассемблером заключается в вычислении логического выражения и включении в объектный модуль первого (фрагмент_программы_1) или второго (фрагмент_программы_2) фрагмента программы в зависимости от того, в какой директиве (IF или IFE) это выражение встретилось.
Если в директиве IF логическое выражение истинно, то в объектный модуль помещается первый фрагмент программы. Если логическое выражение ложно, то при наличии директивы ELSE в объектный код помещается второй фрагмент программы. Если же директивы ELSE нет, то вся часть программы между директивами IF и ENDIF игнорируется, и в объектный модуль ничего не включается. Кстати сказать, понятие'истинности и ложности значения логического выражения весьма условно. Ложным оно будет считаться, если его значение равно нулю, а истинным — при любом значении, отличном от нуля.
Директива IFE аналогично директиве IF анализирует значение логического выражения. Но теперь для включения первого фрагмента программы в объектный модуль требуется, чтобы логическое выражение было ложным.
Директивы IF и IFE очень удобно использовать для изменения текста программы в зависимости от некоторых условий. К примеру, составим макрос для определения в программе области памяти длиной не более 50 и не менее 10 байт (листинг 14.4).
Листинг 14.4. Использование условных директив IF и IFE
<1> ;prg_14_4.asm
<2> masm
<3> model small
<4> stack 256
<5> def_tab_50 macro len
<6> if len GE 50
<7> GOTO exit
<8> endif
<9> if len LT 10
<10>: e x i t
<11>EXITM
<12>endif
<13>rept len
<14>db 0
<15>endm
<16>endm
<17>.data
<18>def_tab_50 15
<19>def_tab_50 5
<20> .code
<21> main:
<22> mov ax,@data
<23> mov ds.ax
<24> exit:
<25> mov ax,4c00h
<26> int 21h
<27> end main
Введите и оттранслируйте листинг 14.4. Не забывайте о том, что условные директивы действуют только на шаге трансляции, и поэтому результат их работы можно увидеть лишь после макрогенерации, то есть в листинге программы. В нем вы обнаружите, что в результате трансляции строка 18 листинга 14.4 развернется в пятнадцать нулевых байтов, а строка 19 оставит макрогенератор совершенно равнодушным, так как значение фактического операнда в строках б и 9 будет ложным. Обратите внимание на то, что для обработки реакции на ложный результат анализа в условной директиве мы использовали макродирективы ЕХПМ и GOTO. Наверное, в данном случае можно было бы составить более оптимальный вариант макрокоманды для резервирования некоторого пространства памяти в сегменте данных, а данный способ выбран, исходя из учебных целей.
Другой интересный и полезный вариант применения директив IF и IFE — отладочная печать. Суть здесь в том, что в процессе отладки программы почти всегда возникает необходимость динамически отслеживать состояние определенных программно-аппаратных объектов, в качестве которых могут выступать переменные, регистры процессора и т. п. После этапа отладки отпадает необходимость в таких
диагностических сообщениях. Для их устранения приходится корректировать исходный текст программы, после чего подвергать ее повторной трансляции. Но есть более изящный выход. Можно определить в программе некоторую переменную, к примеру debug, и использовать ее совместно с условными директивами IF или IFE:
<1>…
<2> debug equ l
<3>…
<4> .code
<5>…
<б> if debug
<7> ;любые команды и директивы ассемблера
<8> ;(вывод на печать или монитор)
<9> endif
На время отладки и тестирования программы вы можете заключить отдельные участки кода в своеобразные операторные скобки в виде директив IF и ENDIF (строки 6-9 последнего фрагмента), реагирующие на значение логической переменной debug. При значении debug = 0 транслятор полностью проигнорирует текст внутри этих условных операторных скобок; при debug = 1, наоборот, будут выполнены все действия, описанные внутри них.