В.А. Авдеев, В.Ф. Гузик
Компьютеры: шины, контроллеры, периферийные устройства
Учебное пособие. Таганрог: ТРТУ, 2001. - 536 с.
Приложение В. Проверочные задания, основные сведения и примеры программ
Коды клавиатуры
1.1. Формулировка задания
Целью настоящей работы является практическое закрепление
знаний по организации ввода информации с клавиатуры с помощью языка ассемблера
и прерываний MS-DOS и BIOS.
Необходимо написать программу, отображающую на экране
16-разрядные коды вводимых с клавиатуры символов, используя соответствующие
методы преобразования и функции программных прерываний.
1.2. Основные сведения
Программные прерывания позволяют получить доступ к различным
процедурам, существенно облегчающим работу программиста. Эти процедуры при
задании соответствующих функций выполняют вывод информации на дисплей, принтер,
ввод данных с клавиатуры и т.д.
Программирование
с помощью прерываний иногда называют программированием на среднем уровне.
Существуют различные типы прерываний. Основное внимание в этой работе уделяется
прерыванию int 16h (int 10h) и int 21h. Прерывание int 16h вызывает служебные
функции BIOS для стандартной клавиатуры, а int 10h вызывает служебные функции
BIOS по выдаче изображения. Такие же по возможности функции обеспечивает и DOS.
Так, прерывание int 21h осуществляет вызов всех служебных функций DOS. Код
требуемой функции необходимо задать в регистре AH. Данные, которые следует
вывести с помощью DOS, заносятся в DL (DX), а введенная DOS информация помещается
в регистр AL. В табл. 1 приведены некоторые функции прерывания DOS INT 21h.
Таблица 1
AH
|
Вывод
|
Ввод
|
Функции
|
01
|
|
AL
|
Ввод с клавиатуры в режиме ЭХО
|
02
|
DL
|
|
Вывод 1 символа на экран дисплея
|
06
|
DL
|
AL
|
Непосредственный ввод-вывод с использованием пульта
управления
|
08
|
|
|
Ввод с клавиатуры с отображением процесса без ЭХА
|
09
|
DX
|
|
Вывод последовательности символов на экран дисплея
|
Для функций
1, 2 и 8 при нажатии клавиш Ctrl + C управление возвращается DOS.
Программа
вывода символа А на экран дисплея содержит 3 команды:
MOV DL,’A’; загрузка
А
MOV AH,2 ; вывод 1
символа на экран
INT 21h ; вызов
процедуры
Следующий
фрагмент программы выполняет запись в регистр AL считываемого символа с
клавиатуры. Если DL равен 0FFh, то AL готов для приема символа. Кроме того,
флаг ZF, равный 0, указывает на завершение ввода с клавиатуры байта в AL.
Next:
MOV
DL,0FFh ; условие готовности
MOV
AH,6 ; ввод с клавиатуры
INT
21h
JZ Next ; если ZF=1
CALL
Display ; переход на подпрограмму
Прерывание
INT 10h выполняет 16 функций выдачи изображения на экран дисплея. Функция 00
устанавливает режим выдачи изображения. Загрузка кода этой функции выполняется
в регистр AH, а задание текстового или графического режимов выполняется в
регистре AL. Функция 03 определяет 16-цветный текстовый режим при выводе
символа на экран в формате 80 строк ´25 символов.
Эту
установку функции и режима выполняет следующая программа:
MOV AH,00 ;задание
функции 00
MOV AL,03 ;загрузка
режима 80x25
INT 10h
При
установке режима, кроме того, BIOS очищает и буфер памяти экрана.
Для
различных типов адаптеров дисплея выбираются режимы из диапазона 0-15.
Информацию о
текущем видеорежиме можно получить (прочитать) с помощью следующих команд:
MOV AH,15 ;установка
функции 15
INT 10h
При этом в
AL помещается текущий режим дисплея, в AH – число символов в строке, а в BH –
номер активной страницы.
Функция 14
осуществляет запись символа в режиме телетайпа. Символ помещается на текущее
место курсора, а курсор сдвигается на одну позицию. В регистре AH задается код
14, в регистре AL – записываемый символ ASCII и в регистре BH – номер активной
страницы для текстового режима.
Программа
вывода символа на экран дисплея имеет вид:
MOV AL,’B’ ;загрузка
В
MOV AH,14 ;режим
телетайпа
MOV BH,0 ;страница
0
MOV
DX,0 ;строка 0, столбец 0
INT
10h
Процедура
для работы с клавиатурой вызывается с помощью прерывания int 16h. Этих процедур
три (0-2). Для вызова процедуры номер ее (номер функции) задается в регистре
AH.
Функция 0
осуществляет чтение с клавиатуры очередного символа. Каждый символ клавиатуры в
буфере представляется в виде двух байтов. Первый (главный) байт, записываемый в
AL равен 0 для специальных клавиш (например, F1—F10) либо коду ASCII для
обычных. Второй (вспомогательный) байт, находящийся в регистре AH, равен номеру
расширенного кода специальных клавиш либо скэн-коду стандартных клавиш для
ASCII-символов. Если символа нет в буфере, то процедура ждет его появления.
Рассмотрим
программу, которая ждет от клавиатуры появления символа в AL. Если в AL код 0,
то в AH находится номер расширенного кода.
mov ah,0 ;ожидание
символа
int 16h
cmp al,0 ;проверка
на расширенный код
je ext_cod ;переход
на подпрограмму
Функция 1
выполняет проверку о наличии символа в буфере. Если ZF= 1, то это указывает на
отсутствие символа, а 0 – на его наличие. При наличии символа он размещается в
регистрах AL и AH так же, как и для функции 0.
Например,
mov ah, 1 ;проверяем
наличие символа
int 16h
jz no_cod ;переход,
если нет символа
cmp al, 0 ;проверка
на расширенный код
je ext_cod;переход
на подпрограмму
Функция 1
позволяет получить состояние регистровых клавиш, которое берется из ячейки памяти
с адресом 417 и помещается в AL.
При нажатии
любой из клавиш клавиатура передает в адаптер клавиатуры код, равный порядковому
номеру клавиши и называемый скэн-кодом (кодом сканирования). Например, при
нажатии клавиши А клавиатурой посылается код 30 (1Eh). Этот код преобразуется
BIOS в 2-байтовый. Для обычных клавиш первый байт содержит код ASCII, а второй
– скэн-код. Например, для клавиши А первый байт имеет код 41h (верхний
регистр), а второй байт – код 1Eh.
Скэн-код
специальной клавиши преобразуется BIOS в 2-байтный код, первый байт которого
содержит 0, а второй байт – номер расширенного кода. Например, нажатию клавиши
F1 соответствует 2-байтоый код 00h; 3Bh (59 = 3Bh).
1.3. Пример выполнения варианта задания
Code Segment
para 'code'
Assume cs: code, ds: code
org 100h
begin:
mov ah,00 ; ввод кода
int 16h
push ax
cmp al,0
jne go1
push ax
mov dl,'0' ;
вывод символа 0
mov ah,2
int 21h
mov dl,' ' ; вывод пробела
int 21h
pop ax
jmp begin
go1:
mov dh,al
mov cl,4 ;
выделение старшей тетрады
shr al,cl
add al,30h
cmp al,39h ;
преобразование
jbe go2
add al,7
go2:
mov dl,al ; вывод символа
mov ah,2
int 21h
mov dl,dh ;
выделение младшей тетрады
and dl,0Fh
add dl,30h
cmp dl,39h ;
преобразование
jbe go3
add dl,7
go3:
mov ah,2 ; вывод символа
int 21h
mov dl,10 ;
перевод строки
int 21h
mov dl,13
int 21h
pop ax
cmp al,27 ; код ESC
jne begin
mov ax,4C00h ;
завершить процесс
int 21h
Code Ends
end begin
Одним из
вариантов задания может служить модификация введенной программы путем ввода
подпрограмм преобразования и вывода кода на заданное место экрана дисплея.
Кроме того, вместо COM-программы можно написать EXE-программу.
1.4. Варианты заданий
На рис.1
изображен морфологический граф, задающий в минимальном объеме 36 вариантов
решения задачи определения шестнадцатеричных кодов клавиш клавиатуры с выводом
этих кодов на экран дисплея.
Первый уровень (вершины 1-3) является системным уровнем.
Вершина 1
определяет функцию BIOS, вершины 2 и 3 – функции DOS, используемые в программе.
Второй
уровень (вершины 4-6) соответствует уровню преобразования кода клавиатуры в
шестнадцатеричную форму.
Вершина 4
указывает на алгоритм перекодировки, использующий таблицу 0-F и индекс.
Применению команды XLAT в программе перевода соответствует
вершина 5.
Рис.1. Морфологический граф вариантов
решения задачи
Арифметический метод преобразования определяет вершина 6.
Вариант задания определяется маршрутом, соединяющим
четыре вершины (по одной из каждого уровня), например, вариант задания 1, 4, 7,
9.
Рассмотрим
подробнее определение вершин морфологического графа.
Необходимые функции BIOS и DOS, соответствующие вершинам
1-3, изложены в разделе 1.2.
Вершине 4 соответствует алгоритм перекодировки, использующий
таблицу и индекс.
В морфологическом графе вершина 5 определяет применение
команды преобразования XLAT. Эта команда использует содержимое регистра AL, как
смещение относительно начала 256-байтовой таблицы TABLE, перемещаемый адрес
начала которой задается регистром BX. Байт таблицы, определяемый этим
смещением, заменяет исходное содержимое AL. Смещение 0 определяет начальный
байт таблиц. В качестве примера использования команды XLAT рассмотрим фрагмент
программы преобразования десятичных чисел от 0 до 15 в соответствующие им
шестнадцатеричные числа от 0 до F.
TABLE db ‘0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F’
mov ax, cs
mov ds, ax
mov si, 0
mov cx, 16
mov bx, offset table
NEXT: mov ax, si
XLAT
mov dl, al
call displ AY
inc si
loop next
В этой программе выполняются следующие действия.
Содержимое DS помещается в CS, так как область TABLE
находится в сегменте кодов.
Для выполнения команды XLAT необходимо поместить в BX адрес
начала таблицы. Затем содержимое SI пересылается в AX (AL) и по команде XLAT
происходит преобразование десятичного числа в шестнадцатеричное.
Преобразованное значение формируется в AL. Содержимое AL перезаписывается в DL
и выводится на экран дисплея. Команда INC увеличивает содержимое SI на 1. Затем
при выполнении команды LOOP содержимое регистра CX уменьшается на 1. Если CX =
0, то управление передается на метку NEXT, а если CX = 0, то это конец выполнения
программы. Вершина 6 морфологического графа соответствует арифметическому
преобразованию двоичных кодов в шестнадцатеричную форму без применения таблицы.
Алгоритм заключается в выделении старшей тетрады. Если старшая тетрада меньше
или равна 9, то к ней добавляется 30h, а если больше, то добавляется 37h.
Аналогичным образом обрабатывается младшая тетрада.
Определение кода нажатой клавиши возможно с помощью
прерывания BIOS int 16h с функцией AH = 00 и прерывания DOS int 21h с функцией
AH = 06 или AH = 08.
Прерывание int 16h c функцией AH = 00 помещает в регистр AL
код ASCII нажатой клавиши, причем если нажата функциональная (специальная)
клавиша, то в регистре AL содержится нуль, а в регистре AH – скэн-код нажатой
клавиши.
Прерывание int 21h с функцией AH = 06 возвращает в AL код
нажатой клавиши. Если клавиша не была нажата (буфер клавиатуры пуст), то
устанавливается флаг нуля (ZF = 1). В случае AL = 0 (нажата функциональная
клавиша) необходимо повторить вызов функции.
Процедура прерывания int 21h с функцией AH = 08 ждет, пока не
будет нажата клавиша (флаг ZF не устанавливается) и возвращает ее код в регистр
AL.
Вывод символа на экран выполняется с помощью прерывания DOS
int 21h с функцией AH = 2 или с помощью прерывания BIOS int 10h (AH = 14).
Похожие материалы:
Коды ASCII и расширенные коды
Кодификация международного права (Батычко В.Т., 2011)
Кодификация Юстиниана
Кожгалантерейное производство
Кожевенное и кожсырьевое производства: Раздел ЕТКС
Кокильщик-сборщик
|