В контексте нашего изложения 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, то окно очистится и заполнится строками с цветом,
заданным в ВН. Структура байта атрибута аналогична описанной выше.