Devotes - Предисловие
Уважаеме посетители, Сайт переезжает на другой хост http://www.devote.ru/
   Поиск по сайту:  
» Главная
Книги
Музыка
Download
Форум
[Назад] [Далее]

4.3. Вывод на экран в текстовом режиме

4.3.1. Средства DOS

На примере первой программы на ассемблере мы уже познакомились с одним из способов вывода текста на экран — вызовом функции DOS 09h. Это далеко не единственный способ вывода текста — DOS предоставляет для этого несколько функций.


Функция DOS 02h — Записать символ в STDOUT с проверкой на Ctrl-Break

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

Эта функция при выводе на экран обрабатывает некоторые управляющие символы — вывод символа BEL (07h) приводит к звуковому сигналу, символ BS (08h) приводит к движению курсора влево на одну позицию, символ НТ (09h) заменяется на несколько пробелов, символ LF (0Ah) опускает курсор на одну позицию вниз, и CR (0Dh) приводит к переходу на начало текущей строки.

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

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

; dosoutl.asm
; Выводит на экран все ASCII-символы
;
        .model tiny
        .code
        org         100h           ; начало СОМ-файла
start:
        mov         ex,256         ; вывести 256 символов
        mov         dl,0           ; первый символ - с кодом 00
        mov         ah,2           ; номер функции DOS "вывод символа"
cloop:  int         21h            ; вызов DOS
        inc         dl             ; увеличение DL на 1 - следующий символ
        test        dl,0Fh         ; если DL не кратен 16,
        jnz         continue_loop  ; продолжить цикл,
        push        dx             ; иначе: сохранить текущий символ
        mov         dl,0Dh         ; вывести CR
        int         21h
        mov         dl,0Ah         ; вывести LF
        int         21h
        pop         dx             ; восстановить текущий символ
continue_loop:
        loop        cloop          ; продолжить цикл
        ret                        ; завершение СОМ-файла
        end         start

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

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

hello-1.com > hello-1.out

то на экран ничего выдано не будет, а в текущем каталоге появится файл hello-1.out, содержащий строку «Hello World!». Точно так же, если написать

dosout1.com > dosout1.out

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


Функция DOS 06h — Записать символ в STDOUT без проверки на Ctrl-Break

Ввод: АН = 06h
DL = ASCII-код символа (кроме FFh)
Вывод: Никакого, согласно документации, но на самом деле: AL = код записанного символа (копия DL)

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


Функция DOS 09h — Записать строку в STDOUT с проверкой на Ctrl-Break

Ввод: АН = 09h
DS:DX = адрес строки, заканчивающейся символом $ (24h)
Вывод: Никакого, согласно документации, но на самом деле: AL = 24h (код последнего символа)

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


Функция DOS 40h — Записать в файл или устройство

Ввод: АН = 40h
ВХ = 1 для STDOUT или 2 для STDERR
DS:DX = адрес начала строки
СХ = длина строки
Вывод: CF = 0,
АХ = число записанных байт

Эта функция предназначена для записи в файл, но, если в регистр ВХ поместить число 1, функция 40h будет выводить данные на STDOUT, а если ВХ = 2 — на устройство STDERR. STDERR всегда выводит данные на экран и не перенаправляется в файлы. На этой функции основаны используемые в С функции стандартного вывода — фактически функция С fputs() просто вызывает это прерывание, помещая свой первый аргумент в ВХ, адрес строки (второй аргумент) — в DS:DX и длину — в СХ.

; dosout2.asm
; Выводит на экран строку "This function can print $",
; используя вывод в STDERR, так что ее нельзя перенаправить в файл.
        .model      tiny
        .code
        org         100h                ; начало СОМ-файла
start:
        mov         ah,40h              ; номер функции DOS
        mov         bx,2                ; устройство STDERR
        mov         dx,offset message   ; DS:DX - адрес строки
        mov         cx, message_length  ; CX - длина строки
        int         21h
        ret                             ; завершение СОМ-файла
message db          "Эта функция может выводить знак $"
message_length = $-message              ; длина строки = текущий адрес
                                        ; минус адрес начала строки
        end         start

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

dosout2.com > dosout2.out

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


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


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

Ввод: AL = ASCII-код символа

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


Hosted by uCoz