Иллюстрированный самоучитель по Assembler

Макросредства ассемблера

Директивы условной трансляции

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

Пусть, например, в процессе отладки сложной программы мы используем подпрограмму regs вывода на экран содержимого всех регистров процессора. Включая в разные места программы вызов этой подпрограммы, мы имеем возможность контролировать ход ее выполнения, в том числе и такие тонкие моменты, как, например, расположение программы в памяти или интенсивность использование стека. Для управления процессом трансляции предусмотрим константу debug (отладка), ненулевое значение которой будет требовать отладочного варианта трансляции, а нулевое – рабочего. Начало программы, а также участки с вызовом отладочной подпрограммы будут выглядеть следующим образом:

;debug=1; Удалите символ ';' для отладочной трансляции
;debug=0; Удалите ';' для рабочей трансляции
…; Текст программы
if debug; Транслировать только если debug=1
call regs; Вызов отладочной подпрограммы
endif; Конец блока условной трансляции
…; Продолжение программы
if debug; Следующее включение отладочного блока
call regs
endif
…; Продолжение программы

Разумеется, можно отлаживать программу в отладочном варианте, а затем удалить все вызовы вспомогательной подпрограммы regs вручную и получить рабочий вариант, однако на практике обычно (или даже всегда) оказывается, что после эксплуатации программы в течение некоторого времени в ней обнаруживаются незамеченные ранее ошибки, что приводит к необходимости снова вставлять в нее отладочные строки. Часто эту процедуру приходится повторять многократно. Использование в программе директив условной трансляции сокращают процедуру преобразования программы из отладочного варианта в рабочий или наоборот до операции стирания одного символа ";" в начале программы и устраняют вероятность случайного внесения в программу новых ошибок в процессе удаления или вставки отладочных строк.

Рассмотрим еще один пример применения директив условной трансляции. Как уже отмечалось, современные процессоры предоставляют программисту значительное количество дополнительных команд, которые можно использовать в программах реального режима, но только, разумеется, если компьютер оснащен соответствующим процессором. Нетрудно составить универсальную программу', которую можно выполнять как на современных процессорах (в более эффективном режиме), так и на более старых (с некоторой потерей эффективности), если включить в нее директивы условной трансляции этих дополнительных команд. К таким командам, в частности, относятся команды сохранения в стеке всех регистров общего назначения pusha и восстановления всех регистров рора. Приведем пример условной трансляции этих команд, в котором используется конструкция макроязыка if… else… endif:

i386=l
if i386
.386
endif
code segment use16
assume CS:code
main proc
…
if i386
push; Сохранение всех регистров одной командой
else
push AX
push CX
push DX
push BX
push BP
push SI
push DI
endif
…; Использование регистров после сохранения их значений
if 1386
рора; Восстановление всех регистров одной командой
else
pop DI
pop SI
pop BP
pop BX
pop DX
pop CX
pop AX
endif

Если в начале программы имеется объявление i386=1, то, во-первых, в программу будет включена директива.386, позволяющая использовать в программе дополнительные команды, а во-вторых, в последующих условных блоках будут транслироваться те их участки, которые содержат команды процессора 80386. Если же объявление i386=1 изъять, то в условных блоках будут транслироваться эквивалентные по существу, но менее эффективные последовательности команд МП 86.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.