Заменим в примере № 1.1 MOV АН,2 на MOV АН,6 и перекомпилируем этот пример. Работу откомпилированного примера смотрим в операционной системе MS-DOS.
Функция DOS 09h
Функция DOS 09h - Записать строку в STDOUT с проверкой на Ctrl-Break
Ввод: | АН = 09h DS: DX = адрес строки, заканчивающейся символом $ (24h) |
Вывод: | Никакого, согласно документации, но на самом деле: AL = 24h (код последнего символа) |
Действие этой функции полностью аналогично действию функции 02h, но выводится не один символ, а целая строка (смотри лабораторную работу №2).
1.4 Функция DOS 40h
Функция DOS 40h - Записать в файл или устройство
Ввод: | АН = 40h ВХ = 1 для STDOUT или 2 для STDERR DS: DX = адрес начала строки СХ = длина строки |
Вывод: | CF = 0, АХ = число записанных байт |
Эта функция предназначена для записи в файл, но, если в регистр ВХ поместить число 1, функция 40h будет выводить данные на STDOUT, а если ВХ = 2 - на устройство STDERR. STDERR всегда выводит данные на экран и не перенаправляется в файлы. На этой функции основаны используемые в С функции стандартного вывода - фактически функция С fputs () просто вызывает это прерывание, помещая свой первый аргумент в ВХ, адрес строки (второй аргумент) - в DS: DX и длину - в СХ.
Простой пример работы функции DOS 40h.
Пример № 1.2
. model tiny | ; модель памяти в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov ah,40h | ; номер функции DOS |
mov bx,2 | ; указываем устройство STDERR |
mov dx,offset message | ; DS: DX - адрес строки |
mov cx,25 | ; CX - длина строки |
int 21h | ; вызов DOS |
ret | ; функция DOS "завершить программу" |
message db "This function can print $" | ; cтрока с содержащая выводимые данные. |
end begin | ; метка окончания кода программы |
Если скомпилировать этот пример и запустить ее командой
dosout.com > dosout. out
то сообщение появится на экране, а файл dosout2. out окажется пустым.
Прерывание INT 29H
INT 29h: Быстрый вывод символа на экран
Ввод: | AL = ASCII-код символа |
Простой пример работы прерывания INT 29h.
Пример № 1.3
. model tiny | ; модель памяти в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov ax, < ASCII-код символа > | ; заносим в регистр ax - любой ASCII-код символа |
int 29h | ; вызов прерывания DOS - вызов символа; |
ret | ; функция DOS "завершить программу" |
end begin | ; метка окончания кода программы |
В большинстве случаев INT 29h просто немедленно вызывает функцию BIOS "вывод символа на экран в режиме телетайпа", так что никаких преимуществ, кроме экономии байт при написании как можно более коротких программ, она не имеет.
2. Средства BIOS
Функции DOS вывода на экран позволяют перенаправить вывод в файл, но не позволяют вывести текст в любую позицию экрана и не позволяют изменить цвет текста. DOS предполагает, что для более тонкой работы с экраном программы должны использоваться видеофункции BIOS. BIOS - обеспечивает доступ к некоторым устройствам, в частности к видеоадаптеру. Все функции видеосервиса BIOS вызываются через прерывание 10h.
2.1 Выбор видеорежима
BIOS предоставляет возможность переключения экрана в различные текстовые и графические режимы. Режимы отличаются друг от друга разрешением (для графических) и количеством строк и столбцов (для текстовых), а также количеством возможных цветов.
2.1.1 Стандартные видеорежимы
INT 10h, АН = 00 - Установить видеорежим
Ввод: | AL = номер режима в младших 7 битах |
Вывод: | Обычно никакого, но некоторые BIOS (Phoenix и AMI) помещают в AL 30Н для текстовых режимов и 20h для графических |
Пример работы.
Пример № 2.1
. model tiny | ; модель памяти в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov ah,00 | ; устанавливаем видеорежим |
mov al,5 | ; устанавливаем номер режима |
int 10h | ; вызов прерывания DOS - вызов видеосервиса; |
ret | ; функция DOS "завершить программу" |
end begin | ; метка окончания кода программы |
Вызов этой функции приводит к тому, что экран переводится в выбранный режим. Если старший бит AL не установлен в 1, экран очищается. Номера текстовых режимов - 0, 1, 2, 3 и 7.0 и 1 - 16-цветные режимы 40x25 (с 25 строками по 40 символов в строке), 2 и 3 - 16-цветные режимы 80x25, 7 - монохромный режим 80x25. Существует еще много текстовых режимов с более высоким разрешением (80x43, 80x60, 132x50 и т.д.), но их номера для вызова через эту функцию различны для разных видеоадаптеров (например, режим 61h - 132x50 для Cirrus 5320 и 132x29 для Genoa 6400). Однако, если видеоадаптер поддерживает стандарт VESA BIOS Extention, в режимы с высоким разрешением можно переключаться, используя функцию 4Fh.
2.1.2 SuperVGA-видеорежим
INT 10h, АН = 4Fh, AL = 02 - Установить SuperVGA-видеорежим
Ввод: | ВХ = номер режима в младших 13 битах |
Вывод: | AL = 4Fh, если эта функция поддерживается АН = 0, если переключение произошло успешно АН = 1, если произошла ошибка |
Если бит 15 регистра ВХ установлен в 1, видеопамять не очищается. Текстовые режимы, которые можно вызвать с использованием этой функции: 80x60 (режим 108h), 132x25 (109h), 132x43 (10Ah), 132x50 (10Bh), 132x60 (10Ch).
Видеорежим, используемый в DOS по умолчанию, - текстовый режим 3.
2.2 Управление положением курсора
2.2.1 Устанавливаем положение курсора
INT 10h, АН = 02 - Установить положение курсора
Ввод: | АН = 02 ВН = номер страницы DH = строка DL = столбец |
Пример работы.
Пример № 2.2.1
. model tiny | ; модель памяти, в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov ah,02 | ; устанавливаем положение курсора |
mov bh,0 | ; устанавливаем номер страницы |
mov dh,12 | ; строка 12 |
mov dl,29 | ; столбец 29 |
int 10h | ; прерывания DOS - установить положение курсора в точку 12,29 |
mov ax, < ASCII-код символа > | ; заносим в регистр ax - любой ASCII-код символа |
int 29h | ; вызов прерывания DOS - вызов символа; |
ret | ; функция DOS "завершить программу" |
end begin | ; метка окончания кода программы |
С помощью этой функции можно установить курсор в любую позицию экрана, и дальнейший вывод текста будет происходить из этой позиции. Отсчет номера строки и столбца ведется от верхнего левого угла экрана (символ в левой верхней позиции имеет координаты 0,0). Номера страниц 0 - 3 (для режимов 2 и 3) и 0 - 7 (для режимов 1 и 2) соответствуют области памяти, содержимое которой в данный момент отображается на экране. Можно вывести текст в неактивную в настоящий момент страницу, а затем переключиться на нее, чтобы изображение изменилось мгновенно.
2.2.2 Считываем положение и размер курсора
INТ 10h, АН = 03 - Считать положение и размер курсора
Ввод: | АН = 03 ВН = номер страницы |
Вывод: | DH, DL = строка и столбец текущей позиции курсора СН, CL = первая и последняя строки курсора |
Возвращает текущее состояние курсора на выбранной странице (каждая страница использует собственный независимый курсор).
2.3 Вывод символов на экран
Каждый символ на экране описывается двумя байтами - ASCII-кодом символа и байтом атрибута, указывающим цвет символа и фона, а также является ли символ мигающим.
Атрибут символа:
Бит 7: символ мигает (по умолчанию) или фон яркого цвета (если его действие было переопределено видеофункцией 10h).
Биты 6 - 4: цвет фона. Бит 3: символ яркого цвета (по умолчанию) или фон мигает (если его действие было переопределено видеофункцией 11h).
Биты 2 - 0: цвет символа.
Цвета кодируются в битах, как показано в таблице №2.3 .
Таблица №2.3 Атрибуты символов
Обычный цвет | Яркий цвет | |
000b | черный | темно-серый |
001b | синий | светло-синий |
010b | зеленый | светло-зеленый |
011b | голубой | светло-голубой |
100b | красный | светло-красный |
101b | пурпурный | светло-пурпурный |
110b | коричневый | желтый |
111b | светло-серый | белый |
2.3.1 Считываем символ и атрибут символа в текущей позиции курсора.
INT 10h, АН = 08 - Считать символ и атрибут символа в текущей позиции курсора
Ввод: | АН = 08 ВН = номер страницы |
Вывод: | АН = атрибут символа AL = ASCII-код символа |
2.3.1 Выводим символ с заданным атрибутом на экран
INT 10h, АН = 09 - Вывести символ с заданным атрибутом на экран