Сборник по задачам и примерам Assembler



Функции BIOS для работы с консолью

В контексте нашего изложения ROM BIOS (Read Only Memory Basic Input Output System) представляет собой совокупность программ в энергонезависимой памяти компьютера, одной из задач которых является устранение специфики аппаратных компонент компьютера для функционирующего на нем программного обеспечения, включая операционную систему. Обслуживание клавиатуры и монитора выполняют программы BIOS, называемые драйверами. Структурно драйверы состоят из ряда подпрограмм, называемых функциями, каждая из которых выполняет определенные действия. Обращение к функциям BIOS производится аналогично обращению к функциям MS DOS. Для работы с клавиатурой и экраном BIOS содержит два программных прерывания — 16h и 10h, обращение к которым, исходя из вышесказанного, является обращением к драйверам этих устройств. Для вызова этих прерываний, как обычно, используется команда INT — int 16h или int 10h. Для выполнения определенной операции в регистре АН указывается номер функции. При необходимости в других регистрах может указываться дополнительная (параметрическая) информация. Ниже рассмотрим подробнее возможности BIOS для работы с консолью.

Функции BIOS для работы с клавиатурой

Прерывание 16 BIOS имеет функции для различных типов клавиатур: обычной —
84 клавиши и двух типов расширенной клавиатуры — 101\102 и 122-клавишной.
Выяснить функциональные возможности клавиатуры позволяет функция 09п:

Вход: АН - 09h.
Выход: AL = битовое поле, установленные биты которого обозначают поддерживаемые функции: 7 - резерв; 6 — поддержка клавиатуры со 122 клавишами (и функций 20h-22h (int 16h)); 5 — поддержка расширенной клавиатуры со 101-102 клавишами (и функций 10h-12h (int 16h)); 4 — поддержка функции 0Ah (int 16h); 3 — поддержка функции 0З0бп (int 16h); 2 — поддержка функции 0305h (int 16h); 1 — поддержка функции 0304h (int 16h); 0 — поддержка функции 0З00п (int 16h).

Прежде чем вызывать эту функцию, необходимо удостовериться в том, что
она поддерживается данной версией BIOS. Сделать это можно, вызвав функцию
OcOh прерывания int 15h.

Вход: АН = COh получить конфигурацию.
Выход: CF = 1 — BIOS не поддерживает эту функцию; CF - 0 — в случае успеха: ES:BX — адрес конфигурационной таблицы в ROM-памяти; АН = состояние (ООп — успех; 8бп — функция не поддерживается).

Формат конфигурационной ROM-таблицы:

Смещение Размер Описание
00h 2 байта Число байтов в этой таблице
02h 1 байт Модель BIOS
03h 1 байт Подмодель BIOS
04h 1 байт Издание BIOS:
0 — 1-я редакция,
1 — 2-я редакция и т. д.
05h 1 байт 1-й байт свойств
06h 1 байт 2-й байт свойств
07h 1 байт 3-й байт свойств
08h 1 байт 4-й байт свойств
09h 1 байт 5-й байт свойств

Если в результате этого вызова бит б второго байта свойств установлен, то BIOS поддерживает функцию 09п прерывания int 16h, с помощью которой определяются функциональные возможности клавиатуры.

Вход: АН = 10h, 20h чтение символа с ожиданием (для 101-102- и 122-клавиш-ных клавиатур соответственно).
Выход: для обычных клавиш (АН = скан-код BIOS; AL = символ ASCII); для клавиш и комбинаций с расширенным кодом (АН = расширенный ASCII-код; AL = 0); для дополнительных клавиш (АН - расширенный ASCII-код; AL = 0Eh).
Для ввода строки символов данные функции необходимо использовать в цикле. На примере показанной ниже программы, используя отладчик, можно исследовать содержимое АХ при нажатии различных клавиш и их комбинаций.

;prg05_02.asm - программа на ассемблере для ввода строки ;с использований функции ввода символа 10h
.data
string db 5 dup (0) len_string =$-string adr_stringdd string .code
mov cx,len_string
les di.adr_string ml: mov ah.O10h
int 16h
stosb
loop ml

Программа вводит 5 символов и сохраняет их в строке str.

Проверка наличия символа (01h, 11h, 21h int 16h)

Вход: АН = Olh проверка наличия символа (для 84-клавишной клавиатуры).
Выход: если ZF=O, то регистры АН и AL содержат: для обычных клавиш (АН = скан-код BIOS; AL = символ ASCII); для клавиш и комбинаций с расширенным ASCII-кодом (АН = расширенный ASCII-код; AL = 0); если ZF=1, то буфер пуст.

Функция 01h получает информацию о символе, не считывая его из буфера клавиатуры. Исключение составляют нажатия дополнительных клавиш на расширенных клавиатурах, не совместимых с 83\84-клавишными клавиатурами. В процессе проверки функцией Olh они удаляются из буфера. Поэтому при работе с расширенными клавиатурами необходимо использовать функции 11h и 21h.

Вход: АН = llh, 21h проверка наличия символа (для 101-102- и 122-клавишных клавиатур соответственно).
Выход: если ZF=O, то регистры АН и AL содержат: для обычных клавиш (АН = BIOS скан-код; AL - символ ASCII); для клавиш и комбинаций с расширенным кодом (АН = расширенный ASCII-код; AL = 0); для дополнительных клавиш (АН = расширенный ASCII-код; AL = 0eh); если ZF=0, то буфер пуст. В большинстве случаев работу с результатами выполнения данной функции логично начинать с анализа флага ZF (командами JZ или JNZ). Что же касается содержимого регистра АХ, то оно аналогично содержим00h int 16h :пересылаем его:
stosb
jmpml

Получение состояния флагов клавиатуры (02h, 12h, 22h int 16h)

BIOS предоставляет функцию 02h для получения состояния световых индикаторов клавиатуры и некоторых управляющих клавиш.
Вход: АН = 02h получить состояние флагов клавиатуры (для 84-клавишной клавиатуры).
Выход: AL = битовое поле, установленные биты которого соответствуют состоянию следующих флагов: 7 — режим вставки активен; 6 — индикатор CapsLock включен; 5 — индикатор NumLock включен; 4 — индикатор ScrollLock включен; 3 — нажата клавиша Alt (любая клавиша Alt на 101-102-клавишной клавиатуре); 2 — нажата клавиша Ctrl (любая клавиша Ctrl на 101-102-клавишной клавиатуре); 1 — нажата левая клавиша Shift; 0 — нажата правая клавиша Shift.
Поддержка расширенных клавиатур осуществляется функциями 12h и 22h BIOS.
Вход: АН = 12h, 22h получить состояние флагов клавиатуры (для 101-102- и 122-клавишных клавиатур).
Выход: AL = первое битовое поле, установленные биты которого соответствуют состоянию флагов, возвращаемых в регистре AL функцией 02п; АН = второе битовое поле, установленные биты которого соответствуют следующему состоянию флагов: 7 — нажата клавиша SysReq (SysRq); 6 - нажата клавиша CapsLock; 5 — нажата клавиша NumLock; 4 — нажата клавиша Scrolllock; 3 — нажата правая клавиша Alt; 2 — нажата правая клавиша Ctrl; 1 — нажата левая клавиша Alt; 0 — нажата левая клавиша Ctrl.
Кроме этого, состояние данных флагов можно прочитать из оперативной памяти по адресам: 0040h:0017h (AL) и O040h:0010h (АН).

Запись символа в буфер клавиатуры (05h int 16h)

Вход: АН = 05h запись символа в буфер клавиатуры: СН = скан-код; CL = символ ASCII.
Выход: AL = состояние: 00h — успешная запись; Olh — ошибка (буфер клавиатуры заполнен).
С помощью этой функции можно осуществлять подыгрыш для программ, которые ожидают ввода с клавиатуры. Сам буфер клавиатуры организован по принципу кольца, имеет размер 16 байт и занимает в памяти диапазон адресов 0040h:001Eh...0040h:003Dh. В ячейке 0040h:001Ah хранится адрес начала буфера, а в ячейке 0040h: OOlCh — адрес конца. Если содержимое этих ячеек равно, то буфер пуст. Одному символу в буфере соответствует слово, в котором первый байт — скан-код клавиши, а второй — символ ASCII. Исследовать данную функцию можно с использованием операции сцепления (|) MS DOS. Для этого оформим фрагмент кода для определения наличия символа в буфере и его ввода в виде отдельной программы.

В командную строку MS DOS необходимо ввести строку: prog_1.exe | prog_2.exe >p.txt
В результате всех этих действий будет создан файл p.txt, который и будет содержать строку str из файла prog_1.asm.

функции BIOS для работы с экраном

Работа с экраном средствами BIOS производится с помощью набора функций прерывания 10h. С помощью этих функций поддерживаются текстовый и графический режимы работы монитора. В данном разделе будут рассмотрены некоторые функции вывода текста в текстовом режиме.

Установка видеорежима (00h int 10h)

Любой дисплейный адаптер поддерживает несколько текстовых и графических режимов. Переключение между эт000h режимами производится с помощью функции 00h int 10h.
Вход: АН = 00h установить видеорежим: AL - номер видеорежима (если бит 7 регистра AL = 0, то экран очищается, в обратном случае (AL. 7=1) содержимое экрана не изменяется).
Номеров видеорежимов много, нумерация режимов с высоким разрешением (SVGA) зависит от производителя видеоадаптера. Мы не будет приводить никаких сведений по этому поводу, при необходимости информацию о нумерации видеорежимов можно получить из соответствующих источников.

Установка позиции курсора (02h int 10h)

Функция 02h позволяет изменить позицию курсора и сделать ее начальной для последующего вывода. Заметим, что среди функций MS DOS нет подобной функции и функцию 02h int 10h BIOS можно использовать в комбинации с функциями MS DOS для организации форматированного вывода на экран. Вход: АН = 02h — установить позицию курсора: ВН = номер видеостраницы (зависит от используемого видеорежима); DH = строка (00h — верх); DL = ко-" лонка (00h — левая).

Получение позиции курсора (03h int 10h)

Функция 03h позволяет получить текущую позицию курсора. Аналогично ска-I занному выше, среди функций MS-DOS нет подобной функции и функцию 03h > int 10h BIOS также можно использовать в комбинации с функциями MS-DOS. Вход: АН = 03h — получить позицию курсора; ВН - номер видеостраницы (зависит от используемого видеорежима).
Выход: DH = строка текущей позиции курсора (00h — верх); DL - колонка текущей позиции (00h — левая); СН = номер начальной строки курсора; CL = номер последней строки курсора.

Запись символа и его атрибута в видеопамять (09h int 10h)

Функция 09h предназначена для записи ASCII-кода символа и его атрибута непосредственно в видеопамять, причем сделать это можно с количеством повторений, заданных в регистре СХ.
Вход: АН = 09h — запись символа и его атрибута в текущую позицию курсора: ВН = номер видеостраницы; AL = ASCII-код символа; BL = байт-атрибут; СХ = число повторений.
Для вывода одного символа содержимое регистра СХ должно быть равно 1. В текстовом режиме для СХ>1 вывод осуществляется до конца текущей строки, после чего переходит на другую строку.
Кодировка байта-атрибута в этой и других функциях производится в соответствии со следующими таблицами.

Номера битов
Значение
7 Мигающий символ
6..4 Цвет фона
3 Символ яркого цвета
2..0 Символ цвета

 

Биты
Цвет
Яркий цвет
000b
Черный
Темно-серый
001b
Синий
Светло-синий
010b
Зеленый
Светло-зеленый
011b
Голубой
Светло-голубой
100b
Красный
Светло-красный
101b
Пурпурный
Светло-пурпурный
110b
Коричневый
Желтый
111b
Светло-серый
Белый

Чтение символа и его атрибута из видеопамяти (08h int 10h)

В памяти видеоадаптера каждый символ представлен двумя байтами, содержащими ASCII-код символа и его байт-атрибут. Функция 08h BIOS позволяет прочитать код символа и его атрибут непосредственно из видеопамяти.
Вход: АН = 08h — чтение символа и его атрибута в текущей позиции курсора;
ВН = номер видеостраницы. Выход: AL = ASCII-код символа; АН = байт-атрибут.
Ниже приведена программа, которая устанавливает курсор в заданную позицию.

:prg05_04.asm. устанавливающая курсор в заданную позицию.
.code main:
xorbh.bh
mov dh.10
movdl.10
movah.02h
int 10h установили позицию курсора (10.10) записываем символ и атрибут в видеопамять
moval. "a"
mov bl,10001100b :атрибут - ярко-красный мигающий
movcx.5 ;повторить 5 раз
movah.09h
int 10h :прочитаем символ из текущей позиции видеопамяти:
mov ah,08h
int 10h : выясним текущую позицию курсора
хог bh.bh
mov ап.ОЗn
kint 10h установили позицию курсора (10.10)
:все результаты смотрим в отладчике

Важно отметить, что текущая позиция курсора после выполнения функций 08п и 09п осталась неизменной. Отсюда следует важный вывод о том, что при использовании этих функций необходимо также заботиться и о движении курсора функцией 02h. BIOS предоставляет функцию 0Eh, которая выводит символ в режиме телетайпа, предполагающем автоматическую корректировку текущей позиции курсора после вывода символа.

Запись символа в видеопамять (0Ah int 10h)

Функция 0Ah предназначена для записи ASCII-кода символа с текущим значением атрибута в данной позиции непосредственно в видеопамять, причем сделать это можно с количеством повторений, заданных в регистре СХ.
Вход: АН = 0Ah — запись символа в текущую позицию курсора; ВН = номер видеостраницы; AL = ASCII-код символа; СХ = число повторений.
Аналогично функции 09h текущая позиция курсора не изменяется.

Запись символа в режиме телетайпа (0Eh int 10h)

Функция 0Eh выводит символ в текущую позицию курсора с автоматическим ее смещением (в отличие от функций 09h и 0Ah).
Вход: АН = 0Eh — запись символа в текущую позицию курсора; ВН = номер видеостраницы; AL ¦¦ ASCII-код символа; СХ = число повторений.
Запись символа в последнюю позицию строки автоматически переводит кур-Ь cop в первую позицию следующей строки.

Вывод строки (13h int 10h)

Эта функция появилась в BIOS компьютеров архитектуры AT.
Вход: АН = 13h вывод строки (AT); AL = режим записи: бит 0 — после вывода курсор в конец строки; бит 1 — каждый символ в строке представлен двумя байтами: байтом с ASCII-кодом и байтом-атрибутом; бит 2..7 — резерв; ВН = номер видеостраницы; BL = байт атрибут, если строка содержит только символы (AL. 1=0); СХ = число символов в строке; DH, DL = строка и столбец начала вывода строки; ES: ВР — адрес в памяти начала строки.

Обратите внимание, что содержимое строки для вывода может быть двух типов: с байтом-атрибутом, сопровождающим каждый символ строки, и без байта-атрибута. В последнем случае строка состоит из одних кодов символов с единым значением байта-атрибута, указываемым в регистре BL.
Как видно из рассуждения выше, многие функции BIOS работают непосредственно с видеопамятью. Из-за того что для видеопамяти отводится определенный диапазон адресов (для текстового режима — это 0b800h:0000h), доступ к ней можно производить обычными командами работы с памятью микропроцессора, в том числе и цепочечными.

Перемещение в окне вверх (06h int 10h)

Функция 06h позволяет определить на экране окно, в котрром возможно прокрутить определенное количество строк вверх. При такой прокрутке верхние строки исчезают и снизу добавляются пустые строки.
Вход: АН = 06h — перемещение строк в окне вверх; AL = число строк для заполнения снизу; ВН = атрибут символов (цвет) в строке для заполнения; СН и CL = строка и столбец верхнего левого угла окна; DH и DL = строка и столбец нижнего правого угла окна.
Строки для заполнения снизу имеют цвет, определенный в ВН. Если указать AL=0, то окно очистится и заполнится строками с цветом, заданным байтом-атрибутом в ВН.
Ниже приведена программа вывода нескольких строк на экран, после чего она определяет окно на экране и прокручивает его на несколько строк вверх.

:prg05_05.asm - программа для работы с окном на экране.
.data
String db "dfsh3453637869uioraepBBanB"
Ien_str1ng »$-string
adr_stringdd string
. code
..........
movcx,25 ml: mov al ,1 :после вывода - курсор в конец строки
xorbh.bh :номер видеостраницы
movbl.7 : атрибут push ex
mov cx,len_string :длина выводимой строки
les bp.adr_string :адрес строки в пару ES:BP
mov ah,l3h
int l0h
incdh ;строка начала вывода
incdl : столбец начала вывода pop ex
loop ml ¦.определяем и прокручиваем окно вверх
mov al.4 :4 строки
mov bh. 0
mov ch, 5
mov cl .5 . mov dh. 10
mov dl.30
mov ah.06h
int 10h

Заметьте, что функция 06h достаточно гибко работает с курсором.
Перемещение в окне вниз (07h int 10h)
Функция 07h позволяет определить на экране окно, в котором возможно прокрутить определенное количество строк вниз. При такой прокрутке нижние строки исчезают и сверху добавляются пустые строки.
Вход: АН = 07h — перемещение строк в окне вниз; AL = число строк для заполнения сверху; ВН = атрибут символов (цвет) в строке для заполнения; СН и CL - строка и столбец верхнего левого угла окна; DH и DL = строка и столбец нижнего правого угла окна.
Строки для заполнения сверху имеют цвет, определенный в ВН. Если указать А1_=0, то окно очистится и заполнится строками с цветом, заданным в ВН. Структура байта атрибута аналогична описанной выше.


Книжный магазин