Автор: Пользователь скрыл имя, 07 Декабря 2012 в 11:25, реферат
Ассемблер является одним из самых старых из существующих на сегодня языков. Когда-то это был основной язык, но со временем появились более удобные средства общения с компьютером. Тем не менее язык не стал «мертвым» языком. Ассемблер, по словам В.Ю. Пирогова, – “это язык процессора и, следовательно, он будет нужен до тех пор, пока будут существовать процессоры” [11]. Являясь, по сути, символическим представлением машинного языка, Ассемблер позволяет в случае необходимости разрабатывать высокоэффективные программы, решая проблемы, связанные, в частности, с аппаратурой компьютера. Особенно ценен он в особых случаях, когда существуют жесткие ограничения на использование памяти или программа “критична” по времени
Примечания
1 В 16-ричной системе счисления номера строк (столбец hex) соответствуют первой цифре в коде символа, столбцов (строка hex) – второй. Например, код большой латинской буквы А – 41h.
2 Для получения кода в 10-тичной системе счисления следует к соответствующей величине из столбца dec прибавить число из строки dec. Таким образом, код большой латинской буквы А: 64+1=65.
Контроллер связан с процессором 8-битной шиной данных и двумя 8-битными портами: ввода и вывода (таблица 1.5).
Таблица 1.5 - Регистры контроллера клавиатуры [8]
Порт |
Режим работы |
Назначение |
60h |
Чтение / Запись |
Регистр данных / команд |
64h |
Чтение |
Регистр состояния Бит 7 – ошибка четности Бит 6 – тайм-аут приемника/общий тайм-аут Бит 5 – тайм-аут передатчика Бит 4 – состояние «замка» клавиатуры Бит 3 – признак записи команды / данных Бит 2 – признак типа последнего общесистемного сброса Бит 1 – признак наличия данных во входном буфере: 0 - входной буфер свободен (готовность к приему команды / данных) 1 - входной буфер полон Бит 0 – признак наличия данных в выходном буфере: 0 - выходной буфер свободен 1 - выходной буфер полон |
Схема программирования контроллера клавиатуры
а) Запрет прерывания
CLI
б) Ожидание готовности контроллера к приему команды / данных
xor CX, CX ; CX - счетчик количества повторений цикла
выход по счетчику более чем через 65 тысяч повторов
wait1: in AL, 64h ; чтение регистра состояния
test AL, 00000010b ; анализ бита №1 - входной буфер свободен?
loopnz wait1 ; если бит №1 не нуль (буфер не освободился ) и CX≠0,
; переход на метку wait1
jnz err ; анализ причины выхода из цикла:
; если бит №1 не нуль (буфер так и не освободился),
;переход на метку err
………
err: …… ; действия при ошибке
в) Отправка команды
mov AL, <команда>
out 60h, AL
г) Если в команде больше одного байта или нужно дополнительно передать параметры, то необходимо:
дождаться готовности контроллера к приему (повторить п. б), так как входной буфер может быть занят отправленной командой;
отправить следующий байт (аналогично п. в).
д) Разрешение прерываний
STI
Некоторые команды контроллера клавиатуры
Команда EDh. Управление светодиодами (индикаторами состояния) клавиатуры
Позволяет включать и отключать светодиоды CapsLock, NumLock и ScrollLock. Команда двухбайтная – следующий за кодом команды байт имеет формат:
Бит |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Содержимое |
0 |
0 |
0 |
0 |
0 |
CapsLock |
NumLock |
ScrollLock |
=1 - включить
=0 - выключить
компьютер периферийный программирование ассемблер
Команда EEh. Эхо-диагностика.
В ответ микропроцессор выдает код EEh. Используется при возникновении ошибок в работе клавиатуры.
Прочие команды подробно описаны в литературе [8, 11].
Два байта состояния клавиатуры записываются в область данных BIOS по адресам 0000h:0417h (0040h:0017h) и 0000h:0418h (0040h:0018h) [6]. В таблице 1.6 представлены форматы указанных байтов.
Таблица 1.6 - Форматы байтов состояния клавиатуры
Бит № |
Формат байта | |
0000h:0417h |
0000h:0418h | |
Если бит=1, нажата клавиша (включен режим): | ||
0 |
Shift правая |
Ctrl левая |
1 |
Shift левая |
Alt левая |
2 |
Ctrl любая |
Ctrl правая |
3 |
Alt любая |
Alt правая |
4 |
ScrollLock |
ScrollLock |
5 |
NumLock |
NumLock |
6 |
CapsLock |
CapsLock |
7 |
Insert |
SysReq |
ПРИМЕР Протестировать состояние индикатора NumLock.
Comment * Чтобы прочитать байт состояния, необходимо в команде указать его полный адрес 0000h:0417h, так как по умолчанию данные сегментируются по регистру DS, что по условию задачи неприемлемо. В связи с ограничениями, налагаемыми командой mov на типы операндов, пересылка нуля в сегментный регистр ES выполняется за несколько шагов*
xor AX, AX ; 0 à AX
mov ES, AX; ; AX à ES , т.е. 0 à ES
mov AL, ES:[417h] ; в AL – байт состояния
test AL, 100000b ; анализ бита № 5
jz net ; если бит = 0 (NumLock выключен), переход на метку net
; иначе (NumLock включен) – переход на следующую команду
………… ; действия, если NumLock включен
net:…………. ; действия, если NumLock выключен
Основное назначение прерывания BIOS INT 16h – работа с буфером и байтами состояния клавиатуры. Буфер клавиатуры – это кольцевой буфер, используемый для хранения кодов пятнадцати введенных символов. Ряд функций INT 16h представлен в таблице 1.7.
Таблица 1.7 – Функции BIOS - прерывание INT 16h
Вход |
Назначение |
Выход |
Примечание |
AH = 0h1) |
1. Ждать нажатия клавиши (если буфер клавиатуры пуст) 2. Прочитать код введенного |
AL - ASCII-код введен- ного символа AH - скан-код или AL = 0 AH - скан-код |
Введенный символ не отображается |
ПРИМЕР При нажатии клавиши СТРЕЛКА-ВЛЕВО (расширенный код 0:4Bh) перейти на метку strela, иначе - на метку nestrela. mov ah, 0 int 16h : вызов функции 0 прерывания 16h cmp al, 0 ; al=0? (это расширенный код?) jne nestrela ; если AL ¹ 0 à на nestrela ; если AL = 0 (код расширенный) – переход на следующую команду cmp ah, 4Bh ; второй байт кода = 4Bh? (это СТРЕЛКА-ВЛЕВО?) jne nestrela ; если AH ¹ 4Bh à на nestrela, ; иначе à на следующую команду strela: ……….….
nestrela: …………. | |||
AH = 1h2) |
Проверка наличия символа в буфере клавиатуры (символ не удаляется из буфера) |
Если символ есть: ZF = 0 AL и AH – как у функции 0h Если символа нет: ZF = 1 |
|
AH = 2h3) |
Получить состояние |
AL - байт состояния переключающих клавиш (совпадает с байтом 0000h:0417h) |
|
ПРИМЕР Протестировать состояние индикатора NumLock mov ah,2 int 16h ; в AL - байт состояния test al, 100000b ; анализ бита № 5 jz net ; если бит =0 (NumLock выключен), переход на метку net ; иначе (NumLock включен) – переход на следующую команду …………; действия, если NumLock включен net:………. ; действия, если NumLock выключен |
Примечания - Обрабатывает только комбинации, использующие клавиши 84-клавишной клавиатуры. Для 101/105-клавишных и 122-клавишных клавиатур применяются соответственно функции:
1) 10h, 20h
2) 11h, 21h
3) 12h, 22h
Подробнее о специальных функциях, обслуживающих расширенные клавиатуры, - в [8].
Клавиатурные функции MS DOS работают со стандартными устройствами ввода-вывода (таблица 1.8).
Таблица 1.8 – Некоторые функции прерывания INT 21h
Вход |
Назначение |
Выход |
Примечание | ||||||||||||||
Функции ввода | |||||||||||||||||
АН = 1h |
1. Ждать нажатия клавиши. 2. Прочитать код введенного символа |
AL - ASCII-код символа Если AL=0 (признак символа с расширенным кодом), вызвать вторично для получения скан-кода |
Функции отличаются по признаку «Эхо» и реакции на нажатие Ctrl-Break:
| ||||||||||||||
АН = 7h | |||||||||||||||||
АН = 8h | |||||||||||||||||
ПРИМЕР При нажатии клавиши СТРЕЛКА-ВЛЕВО (расширенный код 0:4Bh) перейти на метку strela, иначе на метку nestrela. mov ah, 1 int 21h : вызов функции 1 прерывания 21h cmp al, 0 ; al=0? (это расширенный код?) jne nestrela ; если AL ¹ 0 à на nestrela ; если AL = 0 (код расширенный) – переход на следующую команду Int 21h ; вторичный вызов, в AL второй байт cmp al, 4Bh ; второй байт кода = 4Bh? (это СТРЕЛКА-ВЛЕВО?) jne nestrela ; если AH ¹ 4Bh à на nestrela, ; иначе (это СТРЕЛКА-ВЛЕВО!!!)à на следующую команду strela: ………. ……….. nestrela: ………….. | |||||||||||||||||
АН =Аh DX – начальный адрес буфера памяти, куда будет записана строка |
Чтение строки в память |
Структура буфера памяти: 1-й байт – максимальная длина строки, включая ENTER, - указывает программист 2-й байт – фактическая длина (без ENTER) – заполняет система после ввода строки с 3-го байта – сама строка | |||||||||||||||
АН =Bh |
Чтение состояния клавиатуры |
AL = FFh – буфер пуст AL = 0 – буфер не пуст | |||||||||||||||
Функции вывода | |||||||||||||||||
АН =2h DL – код символа |
Вывод символа |
AL - код последнего записанного символа (исключение: если DL=9 - табуляция, то AL=20h) [6] |
Функции отличаются по реакции на нажатие Ctrl-Break:
| ||||||||||||||
АН =6h DL – код символа | |||||||||||||||||
АН =9h DX – начальный адрес строки (в конце строки - $) |
Вывод строки |
AL-код последнего символа - $ (AL=24h) [6]
|
Примечание – Многие функции модифицируют содержимое регистра AL, что необходимо учитывать при использовании в программе прерывания INT 21h
Пример
Формулировка задачи.
Разработать программу, которая предлагает пользователю нажать клавишу либо сочетание клавиш, после чего анализирует сложившуюся ситуацию и выполняет следующие действия:
- если введен символ w, включается индикатор CapsLock, индикаторы NumLock и ScrollLock отключаются, после чего программа завершается;
- при вводе сочетания CTRL+F1 пользователю предлагается дополнительно ввести любой символ отдельно либо в сочетании с левой клавишей SHIFT, после чего выводится сообщение «Левая клавиша SHIFT была (не была) нажата» и программа завершает работу;
- если введен любой не указанный выше символ, программа выводит слово «КОНЕЦ» и завершает работу.
Постановка задачи
Программа должна состоять из блоков, выполняющих функции:
- вывод приглашения к нажатию любой клавиши;
- ввод символа с помощью прерывания INT 21h и его идентификация;
- выполнение действий в зависимости от того, какой символ введен:
если w - работа с индикаторами клавиатуры (блок 1);
если Ctrl+F1 - предлагается ввести любой символ отдельно либо в сочетании с левой клавишей SHIFT; после анализа ситуации выводится сообщение «Левая клавиша SHIFT была (не была) нажата» (блок 2);
если любой другой символ, выводится сообщение «Конец»;
- задержка до нажатия любой клавиши (используется прерывание INT 16h) перед выходом из программы для того, чтобы пользователь имел возможность прочитать сообщение, и завершение работы программы.
Конкретизация работы блоков
Блок 1 - реализация алгоритма программирования контроллера клавиатуры.
Блок 2:
- вывод приглашения к нажатию клавиши Shift отдельно либо в сочетании с любой другой;
- получение байта состояния клавиатуры с адресом 0000h:0417h (обращением к памяти);
- тестирование бита № 1, который отслеживает текущее состояние левой клавиши SHIFT, и вывод соответствующего сообщения.
Листинг программы
model small
.stack 100h
.data
Press db 10, 13, 'Нажмите любую клавишу $'
PressShift db 10, 13, 'Нажмите клавишу отдельно либо с левым Shift$'
ShiftDa db 10, 13, 'Левый Shift был нажат$'
ShiftNet db 10, 13, 'Левый Shift не был нажат$'
konec db 10, 13, 'Конец','$'