Консалтинговая компания Консалтер.Ру
Главная Новости Библиотека Исследования Законодательство Консалтинг Бизнес-форумы Контакты

Реклама

Рекомендуем



Консалтер.Ру > Библиотека > Информационные технологии

В.А. Авдеев, В.Ф. Гузик
Компьютеры: шины, контроллеры, периферийные устройства

Учебное пособие. Таганрог: ТРТУ, 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)
Кодификация Юстиниана
Кожгалантерейное производство
Кожевенное и кожсырьевое производства: Раздел ЕТКС
Кокильщик-сборщик



О сайте   Авторам   Реклама и услуги   Контакты
Copyright © 2007-2021, Консалтер.Ру