4.3.1. Средства DOS

На примере первой ассемблерной программы мы уже познакомились с одним

из способов вывода текста на экран - вызовом функции DOS 09h. Это далеко не

единственный способ вывода текста - DOS предоставляет для этого несколько

функций.

Функция DOS02h: Записать символ в STDOUT с проверкой на Ctrl-Break Вход:    АН - 02h

DL = ASCII-код символа Выход:  Никакого, согласно документации, но на самом деле:

AL = код последнего записанного символа (равен DL, кроме случая, когда DL = 09h (табуляция), тогда в AL возвращается 20h).

Данная функция обрабатывает некоторые управляющие символы: при выводе символа BEL (07h) появляется звуковой сигнал, посредством BS (08h) курсоршштш

Основы программирования для MS DOS

перемещается влево на одну позицию, символ НТ (09h) используется для замены на несколько пробелов, символ LF (OAh) - для перевода курсора на пози­цию вниз, a CR        - для перехода на начало текущей строки.

Если в ходе работы этой функции была нажата комбинация клавиш Ctrl-Break, вызывается прерывание 23h, которое по умолчанию осуществляет выход из программы.

Например, напишем программу, выводящую на экран все ASCII-символы, 16 строк по 16 символов в строке.

; dosoutl.asra

;  Выводит на экран все ASCII-символы

 

.model

tiny

 

 

.code

 

 

 

org

100h

Начало СОМ-файла.

start:

 

 

 

 

niov

cx,256

Вывести 256 символов.

 

mov

dl,0

Первый символ - с кодом 00.

 

mov

ah,2

Номер функции DOS  "вывод символа".

cloop:

int

21 h

Вызов DOS.

 

inc

dl

Увеличение ВВ на 1 - следующий символ,

 

'test

dl.OFh

Если DL не кратен 16,

 

jnz

continue_loop

продолжить цикл,

 

push

dx

Иначе: сохранить текущий символ,

 

mov

dl.ODh

вывести CR,

 

int

21h

 

 

mov

dl.OAh

вывести

 

int

21h

 

 

pop

dx

восстановить текущий символ,

continue_loop:

 

 

 

loop

cloop

продолжить цикл.

 

ret

 

Завершение СОМ-файла.

 

end

start

 

Это программа типа СОМ, и компилироваться она должна точно так же, как hello-l.asm из раздела 4.1. Здесь с помощью команды ШОР оформляется цикл, выполняющийся 256 раз (значение регистра СХ в начале цикла). Регистр DL со­держит код символа, который равен нулю в начале цикла и увеличивается каж­дый раз на 1 командой INC DL. Если значение DL сразу после увеличения на 1 кратно 16, оно временно сохраняется в стеке и на экран выводятся символы CR и LF, выполняющие переход на начало новой строки. Проверка осуществляется командой TEST DL,0Fh - результат операции AND над DL, и OFh = 0, только если младшие четыре бита DL равны нулю, что и соответствует кратности шестнадцати.

Все функции DOS вывода на экран используют устройство STDOUT, стандар­тный вывод. Это позволяет перенаправлять вывод программы в файл или на стан­дартный ввод другой программы. Например, если написать в командной строке

hello-1.com > hello-Loutто на экране ничего не появится, а в текущей директории появится файл lout, содержащий строку Hello World!. Точно так же, если написать

dosout1.com >dosout1.out

то в файле dosoutl.out окажутся все символы ASCII, причем символы BEL и BS не будут интерпретироваться и запишутся в файл как есть. Символы CR и LF тоже запишутся как есть, но поскольку они отмечают конец строки, редакторы и про-смотрщики текстовых файлов будут разрывать первую строку символов.

Функция DOS 06k. Записать символ в STDOUT без проверки на Ctrl-Break Вход:   АН = 06b.

DL - ASCII-код символа (кроме OFFh) Выход:   Никакого, согласно но на самом деле:

AL = код записанного символа (копия DL)

Эта функция не обрабатывает управляющие символы (CR, HT и BS вы­полняют свои функции при выводе экран, но сохраняются при перенаправле­нии вывода в файл) и не проверяет нажатие Ctrl-Break. Можно заменить MOV

АН,2 командой MOV АН,6 в программе dosoutl.asm и перекомпилировать этот пример, чтобы получить более полную таблицу символов.

Функция DOS 09k Записать строку в STDOUT с проверкой на Ctrl-Break Вход:    АН = 09h

DS:DX = адрес строки, заканчивающейся символом $ (24h)

Выход:  Никакого, согласно документации, но на самом деле:

AL = 24h (код последнего символа)

Действие этой функции полностью аналогично действию функции 02h, но вы­водится не один символ, а целая строка, как в программах и hello-2.asm.

Функция DOS 40k. Записать в файл или устройство Вход:   АН = 40h

ВХ = 1 для STDOUT или 2 для STDERR DS:DX = адрес начала строки СХ = длина строки

Выход: CF = О,

. АХ = число записанных байтов

Эта функция предназначена для записи в файл, но, если в регистр ВХ поместить число 1, функция 40h будет выводить данные на STDOUT, а если ВХ = 2 - на уст­ройство STDERR. Оно всегда выводит данные на экран и не перенаправляется в файлы. На DOS 40h основаны используемые в С функции стандартного вывода -

фактически функция С fputs() просто вызывает это прерывание, помещая свой

первый аргумент в ВХ, адрес строки (второй аргумент) - в DS:DX и длину - в СХ. ; dosout2.asm

;  Выводит на экран строку "Эта функция может вывозить знак

используя вывод в STDERR,  так что ее нельзя перенаправить в файл.

Основы программирования для DOS

start:

message

.model

tiny

 

. code

 

 

org

lOOh

Начало СОМ-файла.

mov

ah,40h

Номер функции DOS.

mov

bx,2

; Устройство STDERR.

mov

message

- адрес строки.

mov

cx,message_length

СХ - длина строки.

int

21h

 

ret

 

; Завершение СОМ-файла.

 

"Эта функция

может выводить знак $"

length =

$-message

; Длина строки = текущий

 

 

адрес начала строки.

end

start

 

адрес минус

Если скомпилировать эту программу и запустить ее командой dosout2.com > dosout2.out

то сообщение появится на экране, а файл dosout2.out окажется пустым.

И наконец, последняя функция DOS вывода на экран - недокументированное прерывание

INT 29h: Быстрый вывод символа на экран Вход:    AL - ASCII-код символа

В большинстве случаев INT 29h немедленно вызывает функцию BIOS «вы­вод символа на экран в режиме телетайпа», поэтому никаких преимуществ, кро­ме экономии байтов при написании как можно более коротких программ, она не имеет.