Функция DOS 01h - Считать символ из STDIN с эхом, ожиданием и проверкой на Ctrl-Break
Ввод: | АН = 01h |
Вывод: | AL = ASCII-код символа или 0. Если AL = 0, второй вызов этой функции возвратит в AL расширенный ASCII-код символа |
При чтении с помощью этой функции введенный символ автоматически немедленно отображается на экране (посылается в устройство STDOUT - так что его можно перенаправить в файл). При нажатии Ctrl-C или Ctrl-Break выполняется команда INT 23h. Если нажата клавиша, не соответствующая какому-нибудь символу (стрелки, функциональные клавиши Ins, Del и т.д.), то в AL возвращается 0 и функцию надо вызвать еще один раз, чтобы получить расширенный ASCII-код (см. приложение 1).
В трех следующих вариантах этой функции код символа возвращается в AL по такому же принципу.
Функция DOS 08h - Считать символ из STDIN без эха, с ожиданием и проверкой на Ctrl-Break
Ввод: | АН = 08h |
Вывод: | AL = код символа |
Функция DOS 07h - Считать символ из STDIN без эха, с ожиданием и без проверки на Ctrl-Break
Ввод: | АН = 07h |
Вывод: | AL = код символа |
Функция DOS 06h - Считать символ из STDIN без эха, без ожидания и без проверки на Ctrl-Break
Ввод: | АН = 07h DL = 0FFh |
Вывод: | ZF = 1, если не была нажата клавиша, и AL = 00 ZF = 0, если клавиша была нажата. В этом случае AL = код символа |
2.2 служебные функции DOS для работы с клавиатурой.
Кроме перечисленных функций используются некоторые служебные функции DOS для работы с клавиатурой.
Функция DOS 0Bh - Проверить состояние клавиатуры
Ввод: | АН = 0Bh |
Вывод: | AL = 0, если не была нажата клавиша AL = 0FFh, если была нажата клавиша |
Эту функцию удобно использовать перед функциями 01, 07 и 08, чтобы не ждать нажатия клавиши. Кроме того, вызов этой функции позволяет проверить, не считывая символ с клавиатуры, была ли нажата комбинация клавиш Ctrl-Break; если это произошло, выполнится прерывание 23h.
Функция DOS 0Ch - Очистить буфер и считать символ
Ввод: | АН = 0Ch AL = Номер функции DOS (01, 06, 07, 08, 0Ah) |
Вывод: | Зависит от вызванной функции |
Функция 0Ch очищает буфер клавиатуры, так что следующая функция чтения символа будет ждать ввода с клавиатуры, а не использовать нажатый ранее и еще не обработанный символ. Например, именно эта функция используется для считывания ответа на вопрос "Уверен ли пользователь в том, что он хочет отформатировать диск?".
Функции посимвольного ввода без эха можно использовать для интерактивного управления программой.
. model tiny | ; модель памяти, в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
Begin: | ; метка начала кода программы |
call Wait_key | ; вызываем подпрограмму |
cmp al,27 | ; сравниваем значение в al с кодом 27 (ESC) ; если да - то на метку Quit_prog |
je Quit_prog | |
cmp al,0 | ; код клавиши расширенный? (F1-F12 и т.п.) |
je Begin | ; да - повторим запрос... |
call Out_char | ; вызываем процедуру вывода нажатой клавиши на экран |
jmp Begin | ; ждем дальше... |
Quit_prog: | ; метка, на которую придет программа в случае нажатия ESC |
mov al,32 | ; помещаем в AL <пробел> |
call Out_char | ; вызываем процедуру вывода символа в AL |
int 20h | ; выходим... |
Wait_key proc | ; процедура ожидания клавиши от пользователя |
mov ah,10h | ; окончание подпрограммы |
int 16h | ; прерывание DOS |
ret | ; функция DOS "завершить работу процедуры" |
Wait_key endp | ; окончание процедуры Wait_key |
Out_char proc | ; начало процедуры out_char |
push cx | ; сохраним все регистры, которые будут изменены подпрограммой... |
push ax | ;... сделаем это для того, чтобы в последствии не было путаницы |
push es | ; сохраним сегментный регистр |
push ax | ; сохраним AX, т.к в нем код нажатой клавиши... |
mov ax,0B800h | ; установим ES на сегмент видеобуфера |
mov es,ax | |
mov di,0 | ; DI - первый символ первой строки |
mov cx, 2000 | ; выводим 2000 символов (80 символов в строке 25 строк) |
pop ax | ; восстановим код клавиши |
mov ah,31 | ; цвет символа |
Next_sym: | ; метка для цикла |
mov es: [di],ax | ; заносим код клавиши и ее цвет (цвет всегда 31) |
inc di | ; увеличиваем указатель на 2 (первый байт - символ, второй байт - цвет) |
inc di | |
loop Next_sym | ; обработка следующего символа |
pop es | ; восстановим сохраненные регистры и выровним стек |
pop ax | |
pop cx | |
ret | ; вернемся из процедуры |
Out_char endp | ; окончание процедуры Out_char |
end Begin | ; метка окончания кода программы |
Программа делает следующее:
Ждет от пользователя клавиши;
если это расширенный ASCII (F1-F12, стрелки), то игнорирует ее;
если это не расширенный ASCII (A-Z, 0-9 и т.п.) - заполнить экран данным символом;
если нажимаем ESC (27 или 1Bh), то заполнить экран пробелами (mov al,32) и выйти.
Задание для выполнения.
3.1 C помощью редактора эмулятора EMU 8086 напишите программы, исходный текст которых приводится в примерах данной лабораторной работы.
3.2 Создайте исполняемые файлы типа *.com.
3.3 Изучите работу полученных программ.
3.4 Напишите программу для вывода на экран содержимого регистра DS (на основе примера №2.1). Сравните результат работы своей программы и того, что показывает отладчик.
3.5 Опишите работу команд DIV, PUSH, POP, SHL, TEST.
3.6 Установите (найдите адреса и запишите), где находятся числа, помещенные в стек.
3.7 Напишите программу для вывода на экран содержимого регистра СS (на основе примера №3.1).
3.8 Предложите другие способы решения поставленных задач.