Cамоучитель по Assembler




. Вывод программы 2.1.





Как уже отмечалось, при загрузке программы в память в регистры DS и ES заносится сегментный адрес префикса программы, поэтому адресация через ES позволяет прочитать содержимое PSP. Префикс содержит, главным образом, данные, необходимые системе для обслуживания текущей программы, но, кроме того, и несколько команд. В частности, префикс начинается с команды CD 20h, которая уже давно не используется, но в префиксе присутствует ради обеспечения совместимости со старыми версиями DOS. Первый байт этой команды, если его рассматривать, как код символа, соответствует элементу двойной горизонтальной рамки (длинный знак равенства).
Занеся в регистр DS число 40h, мы настроили его на начало области данных BIOS, которая начинается с абсолютного адреса 400h, занимает 256 байт и содержит разнообразные данные, используемые BIOS в процессе обслуживания аппаратуры компьютера. Так, например, по адресу 0 от начала этой области хранится базовый адрес первого последовательного порта; по адресу 8 - адрес первого параллельного порта, а по адресу 491i - код текущего видеорежима. При работе в DOS видеоадаптер обычно настраивается на режим 3 (80x25 символов, 16 цветов). Будучи выведен на экран, код 3 образует изображение червонного туза.
В тех случаях, когда макрокоманды составляются для конкретной программы, они включаются в текст программы так, как это было сделано в примере 2.1. Однако часто программист оформляет в виде макрокоманд стандартные процедуры общего назначения, например, программную задержку или вывод на экран строки текста. В этом случае тексты макроопределений целесообразно поместить в макробиблиотеку.
Макробиблиотека представляет собой файл с текстами макроопределений. Макроопределения записываются в этот файл точно в таком же виде, как и в текст программы. Ниже приведен текст файла макробиблиотеки с произвольным именем MYMACRO.MAC, содержащей две макрокоманды.

;Макрокоманда endpr завершения программы
endpr macro ;Макрокоманда без параметров
mov AX,4C00h
int 2 In
endm ;Конец макрокоманды
;Макрокоманда delay настраиваемой программной задержки
delay macro time ;Параметр - число шагов
locallabell,Iabel2 ;Локальные метки
push CX ;Сохраним внешний счетчик
mov CX,time ;Получим фактический параметр
Iabel2 : push CX ;Сохраним его в стеке
mov CX, 0 ;Пусть будет 64К шагов
labell: loop lanell ;Внутренний цикл
pop CX ;Извлечем внешний счетчик
loop Iabel2 ;Внешний цикл
pop CX ;Восстановим CX программы
endm ;Конец макрокоманды

Для того чтобы транслятору были доступны макрокоманды из файла MYMACRO.MAC, его следует на этапе трансляции подсоединить к исходному тексту программы директивой ассемблера include:

include my macro, mac

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

;debug=l ;Удалите символ ';'для отладочной трансляции


;debug=0 ;Удалите ';' для рабочей трансляции


... ;Текст программы


if debug ;Транслировать только если debug=l


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.

Назад
Начало











Начало  Назад