Функции ввода/вывода DOS.
Дата добавления: 2014-11-27 ; просмотров: 836 ; Нарушение авторских прав
Все функции DOS вызываются прерыванием 21h, при этом в AH содержится номер функции. Ниже везде, где есть слова «стандартный ввод», под ними подразумевается клавиатура, однако ввод может быть переопределен (например, из файла). Аналогично, «стандартный вывод» – экран, но вывод также может быть переопределен (например, в файл). ASCIIZ-строка (нуль-терминированная строка) – это строка символов, заканчивающаяся нулевым символом (код 00h).
1. Ввод символа с отображением. Прерывание 21h функция 01h. Вызов: AH=01h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) и выводит его на стандартный вывод (экран). Если ввод был перенаправлен, то невозможно обнаружить EOF.
— если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h;
— чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
2. Вывод символа. Прерывание 21h функция 02h. Вызов: AH=02h; DL=выводимый символ. Возвращает: ничего. Действие: выводит символ на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить, что нет места на диске.
— если Ctrl+C после вывода символа, то вызавается прерывание 23h;
— если стандартный вывод не был перенаправлен, то символ Backspace (08h) перемещает курсор влево на одну позицию.
3. Прямой консольный ввод/вывод. Прерывание 21h функция 06h. Вызов: AH=06h; DL=действие: если DL=00h-FEh, то вывод; если DL=FFh, то ввод. Возвращает:
если вызов с DL=00h-FEh, то ничего;
если вызов с DL=FFh, то: если есть символ – ZF=0, AL=введенный символ
если нет символа – ZF=1.
Действие: используется, если нужно прочитать или записать все возможные символы и управляющие коды без действий ОС. Читает символ со стандартного ввода или записывает символ на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить EOF или что нет места на диске.
— Никакой реакции на Ctrl+C;
— чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
4. Ввод символа без отображения. Прерывание 21h функция 07h. Вызов: AH=07h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) без отображения на стандартном выводе (экране). Если нет символа, то ждет его появления. Если ввод был перенаправлен, то невозможно обнаружить EOF.
— Никакой реакции на Ctrl+C. Нужно использовать функцию 08h, если реакция требуется;
— чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
5. Ввод символа без отображения. Прерывание 21h функция 08h. Вызов: AH=08h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) без отображения на стандартном выводе (экране). Если нет символа, то ждет его появления. Если ввод был перенаправлен, то невозможно обнаружить EOF.
— если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h. Нужно использовать функцию 08h, если реакции не требуется;
— чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
6. Вывод строки. Прерывание 21h функция 09h. Вызов: AH=09h, DS:DX=сегмент:смещение строки. Возвращает: ничего. Действие: посылает строку символов на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить, что нет места на диске.
— Строка должна заканчиваться на символ $(код 24h), который не выводится. Любые другие символы ASCII, включая управляющие, могут содержаться в строке. Для перевода курсора на начало новой строки нужно вывести строку, содержащую символы «перевод строки»/»возврат каретки»:
string DB 10,13,’$’
или использовать прерывание 10h функцию 02h (см. 6.8.2.).
— Если Ctrl+C нажата на клавиатуре, то вызывается прерывание 23h.
7. Буферизованный ввод с клавиатуры. Прерывание 21h функция 0Ah. Вызов: AH=0Ah, DS:DX=сегмент:смещение буфера. Возвращает: ничего. Действие: читает строку символов со стандарного ввода, до появления символа возврата каретки (0Dh) и помещает в буфер (включая завершающий 0Dh). Символы отображаются на стандартном выводе. Если ввод был перенаправлен, то невозможно обнаружить EOF.
— Буфер, используемый этой функцией, имеет формат(см. табл. 6.4.):
Байт | Описание |
Максимальное количество символов (устанавливается перед вызовом) | |
Количество реально прочитанных символов (устанавливается функцией после ее вызова) | |
2 и след. | Прочитанная строка, заканчивающаяся 0Dh |
— Если буфер заполнился (больше символов, чем максимум), последующий ввод игнорируется и подается сигнал до тех пор, пока не нажата клавиша ENTER;
— Если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h.
8. Проверка состояния ввода.Прерывание 21h функция 0Bh. Вызов: AH=0Bh. Возвращает: AL=00h, если нет символа; AL=FFh, если есть один или более символовhр. Действие: проверяет, есть ли в буфере стандартного ввода символ.
— Если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h.
— Если есть символ, эта функция будет возвращать FFh, пока символ не считан функциями ввода (01h, 07h, и т.д.).
9. Очистка буфера и ввод. Прерывание 21h функция 0Ch. Вызов: AH=0Ch; AL=номер фунции, которая вызывается после очистки буфера; для AL=0Ah –DS:DX=сегмент:смещение буфера. Возвращает: если вызов с AL=01h, 07h, 08h то AL=прочитанный символ; если вызов с AL=0Ah, то ничего. Действие: очищает буфер стандартного ввода, затем вызывает одну из функций ввода (заданную в AL).
— Реакция на Ctrl+C (игнорирует или нет) зависит от вызываемой функции;
— Вызов с AL отличным от 01h, 06h, 07h, 08h, 0Ah просто очищает буфер.
10. Запись в файл или устройство. Прерывание 21h функция 40h. Действие: берет корректный дескриптор файла (от предыдущей операции создания или открытия файла), адрес буфера, длину в байтах, передает данные из буфера в файл и затем обновляет положение указателя в файле. Вызов: AH=40h; BX=дескриптор файла; CX=количество байт, которое надо записать; DS:DX=сегмент:смещение буфера. Возвращает: если нет ошибки: CF=0, AX=количество реально переданных байт; иначе – CF=1, AX=код ошибки.
Ввод информации с клавиатуры средствами MS-DOS
Функции прерывания 21h MS-DOS для ввода информации с клавиатуры
MS-DOS имеет целую группу функций прерывания 21h для выполнения ввода информации с клавиатуры. Последовательность действий системы при вводе с клавиатуры такова. Функция MS-DOS вызывает драйвер клавиатуры, передавая ему запрос на ввод одного символа из буфера клавиатуры. Драйвер, выполняя запрос, обращается к нужной функции прерывания 16h BIOS. ISR BIOS прерывания 16h читает из буфера клавиатуры нужное слово и передает в драйвер. Драйвер возвращает байт (обычно младший) в MS-DOS. Таким образом, функции MS-DOS и опирающиеся на них функции библиотеки Turbo С слабо зависят от особенностей аппаратуры, поскольку система от нее изолирована двумя слоями программного обеспечения — драйверами и BIOSом.
Далее приводится характеристика функций MS-DOS, используемых для ввода с клавиатуры.
AH=01h — ввод с ожиданием со стандартного устройства ввода (клавиатуры). Выполняется «эхо» на экран вводимых символов. ASCII-код прочитанного символа помещается в AL. Если нажимается специальная клавиша, в AL возвращается 0, а второе обращение к функции возвращает расширенный скэн-код клавиши.
AH=06h — ввод-вывод с консоли. Если DL = FFh, выполняется ввод со стандартного устройства ввода без ожидания. Если буфер пуст, функция сообщает об этом установленным в 1 флагом нуля (ZF). В противном случае в регистре AL возвращается ASCII-код прочитанного символа.
AH=07h — ввод с консоли с ожиданием без «эха» на экран. ASCII-код прочитанного символа возвращается в AL. Если нажимается специальная клавиша, передаваемое в AL значение равно нулю, а второе обращение к функции возвращает расширенный скэн-код клавиши. Функция не выполняет «фильтрацию» ввода с клавиатуры. Это значит, что нажатие клавиши Backspace не стирает символ на экране, а только сдвигает курсор. Нажатие ENTER не переводит строку, а только перемещает курсор на начало строки.
AH=08h — подобна АН=07h, за исключением того, что если обнаруживается нажатие комбинации клавиш Ctrl-Break, вызывается прерывание 23h.
AH=0Bh — проверка состояния стандартного ввода. Возвращает в регистре AL значение FFh, если буфер клавиатуры не пуст, и 0 в противном случае. Функцию следует использовать перед выполнением функций АН=01h, 07h и 08h для того, чтобы избежать ожидания ввода, если он отсутствует. Кроме того, функция используется как средство проверки того, нажата ли комбинация клавиш Ctrl-Break, если программа долгое время выполняет работу, не связанную с обращением к функциям MS-DOS. Периодическое выполнение функции позволяет аварийно завершить программу, например, в случае ее зацикливания.
AH=0Ch — ввод с клавиатуры с очисткой буфера. Значение в регистре AL содержит номер выполняемой функции: 01, 06, 07, 08 или 0Ah. Поведение функции и возвращаемые значения описаны ранее в спецификации функций АН=01, 06, 07,08 или 0Ah.
Рассмотренные функции MS-DOS для ввода с клавиатуры могут вызываться напрямую из программы через функции getinterrupt(), int86(), intr() и т.п., либо неявно другими функциями ввода.
4.3.2. Функции библиотеки С++
Выполняет ввод с клавиатуры через функцию MS-DOS АН=07h. Она не выполняет «эхо» вывода на экран. В этой связи полезна для организации интерфейса с пользователем, при котором нажатие той или иной клавиши вызывает немедленную реакцию программы без отображения введенного символа на экране.
int getche (void)
Выполняет небуферизуемый ввод с клавиатуры через функцию MS-DOS AH=07h, но в отличие от предыдущей функции обеспечивает вывод введенного символа на экран. Перевод строки происходит при достижении правой вертикальной границы текущего активного окна.
char *getpass(char * prompt)
Выводит на экран ASCII-строку, на начало которой указывает prompt, a затем принимает с клавиатуры без «эха» строку символов. Вводимые символы (не более 7) помещаются во внутреннюю статическую память. Функция возвращает указатель на внутреннюю статическую строку, переопределяемую каждым новым обращением к функции. Основное назначение данной функции — ввод паролей в программе без отображения их на экран.
Проверяет, пуст ли буфер клавиатуры. Если в буфере есть символы, функция возвращает ненулевое значение, в противном случае она возвращает 0. Использует функцию 0Bh MS-DOS. Является удобным средством предотвращения «зацикливания» при ожидании невозможного в данный момент события. Кроме того, при выполнении функции 0Bh осуществляется проверка нажатия комбинации клавиш Ctrl-Break, что позволяет выполнить аварийное завершение программы.
Ввод информации с клавиатуры средствами BIOS
Интерфейсом программ в персональном компьютере с клавиатурой является прерывание 16h BIOS. Далее приводится описание его функций.
АН = 00h — чтение с ожиданием двухбайтового кода из буфера клавиатуры. Прочитанный код возвращается в регистре АХ: младший байт — в регистре AL, старший — в АН. Если нажата ASCII-клавиша, в AL помещается ASCII-код символа, в АН — скэн-код. При нажатии специальных клавиш AL равен 0, а в АН возвращается расширенный скэн-код.
АН = 0lh — чтение без ожидания двухбайтового кода из буфера клавиатуры. Если буфер пуст, в 1 выставляется флаг нуля ZF. В противном случае в АХ возвращается двухбайтовый код из буфера клавиатуры, но продвижение указателя «головы» буфера не производится, т.е. код «остается» в буфере.
АН = 02h — определение состояния шифт- и триггерных клавиш. В регистре AL возвращается содержимое байта по адресу 40:17h (см. табл. 4.1).
Функция АН = 05h не имеет аналогов в библиотеке Turbo С и может использоваться для имитации нажатии клавиш в демонстрационных программах, программах переноса текста и т.д.
Функции АН = 10 — 12h являются аналогами функций 00 — 02h, но предназначены для использования в компьютерах с клавиатурой 101 /102 клавиши.
Функции АН = 00 — 02h прерывания 16h BIOS положены в основу функции bioskey() библиотеки Turbo С. Далее следует описание этой функции.
int bioskey(int cmd)
Обращается в зависимости от значения в cmd к функциям АН = 00 — 02h прерывания 16h. Возвращаемое функцией значение повторяет значение регистра АХ при выходе из прерывания.
4.5. Предварительная подготовка к работе
1.Ознакомиться с аппаратными средствами компьютера для ввода информации с клавиатуры.
2. Ознакомиться с программными средствами для ввода информации с клавиатуры.
Порядок выполнения работы
1. Разработать, написать и отладить программу управления перемещением символа (например, «*») в пределах заданного на экране окна. Для управления использовать клавиши из набора: «стрелка вверх» (СтВВ), «стрелка вниз» (СтВН), «стрелка вправо» (СтВП), «стрелка влево» (СтВЛ) или функциональные клавиши Fl — F12 (варианты см. в таблице 4.2). Для ввода использовать стандартные функции языка C++. Сохранить отлаженную программу.
2. Изменить программу, заменив стандартные функции библиотеки C++ своими. Для написания функций используйте заданное прерывание (см. таблицу), если его возможностей достаточно. Если его возможностей не достаточно, то замените его по своему усмотрению. Сохраните отлаженную программу.
3. Отлаженные программы предъявить преподавателю.
№ варианта | X1 | Y1 | X2 | Y2 | Вид движения | Клавиши управления | Номер прерывания |
Постоянное | СтВВ, СтВН | INT 21h | |||||
Пошаговое | СтВП, СтВЛ | INT 21h | |||||
Постоянное | F1, F2 | INT 21h | |||||
Пошаговое | Все направления | INT 21h | |||||
Постоянное | F5, F6 | INT 16h | |||||
Пошаговое | F1-F4 | INT 16h | |||||
Постоянное | F9-F12 | INT 16h | |||||
Пошаговое | СтВВ, СтВН | INT 16h | |||||
Постоянное | СтВП, СтВЛ | INT 21h | |||||
Пошаговое | Все направления | INT 21h | |||||
Постоянное | F3, F4 | INT 21h | |||||
Пошаговое | F7, F8 | INT 21h | |||||
Постоянное | СтВВ, СтВН | INT 16h | |||||
Пошаговое | СтВП, СтВЛ | INT 16h | |||||
Постоянное | F9, F10 | INT 16h | |||||
Пошаговое | F11, F12 | INT 16h | |||||
Постоянное | СтВВ, СтВН | INT 21h | |||||
Пошаговое | СтВП, СтВЛ | INT 21h | |||||
Постоянное | F5, F10 | INT 21h | |||||
Пошаговое | F6, F12 | INT 21h |
Содержание отчета
1. Краткие сведения о подсистеме ввода информации с клавиатуры, используемых прерываниях, буфере клавиатуры и функциях обслуживания ввода с клавиатуры.
2. Алгоритмы и тексты отлаженных программ.
4.8. Контрольные вопросы
1. Что относится к устройствам ввода информации в ЭВМ?
2. Как можно классифицировать устройства ввода?
3. Назовите основные характеристики устройств ввода информации.
4. Зачем нужен буфер клавиатуры?
5. Почему существует ввод с буферизацией и без нее?
6. Какие бывают прерывания?
7. Зачем для ввода данных с клавиатуры используют прерывания?
8. Какое прерывание вырабатывается при нажатии клавиши?
9. Назовите основные характеристики системы прерываний.
10. Почему нужны программные прерывания?
11. Почему для организации ввода с клавиатуры используются два программных прерывания INT 21h и INT 16h?
12. Какие функции библиотеки C++ для ввода с клавиатуры Вы знаете?
13. Какие функции прерывания INT 16h Вы знаете?
14. Какие функции прерывания INT 21h Вы знаете?
15. Можно ли в прикладной программе обойтись без ввода с клавиатуры?
Лабораторная работа № 5.
Последнее изменение этой страницы: 2020-06-06; Нарушение авторского права страницы
Fn 00H: завершить программу
Вход
- AH = 00H
- CS = сегмент PSP завершающегося процесса
Выход
Описание:
передает управление на вектор завершения в PSP (выходит в родительский процесс). Идентична функции INT 20H Terminate. регистр CS должен указывать на PSP. восстанавливает векторы прерываний DOS 22H-24H (завершение, Ctrl-Break и Критическая ошибка), устанавливая значения, сохраненные в родительском PSP. выполняет сброс файловых буферов. файлы должны быть предварительно закрыты, если их длина изменилась.
Замечание:
Проще и более аккуратно — использовать функцию DOS Fn 4cH Exit.
Fn 01H: ввод с клавиатуры
Вход
Выход
- AL = символ, полученный из стандартного ввода
Описание:
Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). при распознавании Ctrl-Break выполняется INT 23H.
Замечание:
ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.
Fn 09H: Выдать строку на дисплей
Вход
- AH = 09H
- DS:DX = адрес строки, заканчивающейся символом ‘$’ (ASCII 24H)
Выход
Описание:
строка, исключая завершающий ее символ ‘$’, посылается на стандартный вывод. символы Backspace обрабатываются как в функции 02H Display Char. обычно, чтобы перейти на новую строку, включают в текст пару CR/LF (ASCII 13H и ASCII 0aH). строки, содержащие ‘$’, можно выдать через 40H Write Handle (BX=0).
Fn 06H: Консольный ввод-вывод
Вход
- AH = 06H
- DL = символ (от 0 до 0feH), посылаемый на стандартный вывод
- = 0ffH запрос ввода со стандартного ввода
Выход
- ZF = Сброшен (NZ), если символ готов ҐҐЈҐ при запросе ввода
Описание:
при DL = 0ffH выполняет ввод с консоли «без ожидания», возвращая взведенный флаг нуля (ZF), если на консоли нет готового символа. если символ готов, сбрасывает флаг ZF (NZ) и возвращает считанный символ в AL. если DL не равен 0ffH, то DL направляется на стандартный вывод.
Замечание:
Не проверяет Ctrl-Break. вызывайте дважды для расширенного ASCII.
Fn 0aH: ввод строки в буфер
Вход
- AH = 0aH
- DS:DX = адрес входного буфера (смотри ниже)
Выход
- нет = буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
Описание:
при входе буфер по адресу DS:DX должен быть оформлен так:
¦max¦ ? ¦ ? ? ? ? ? MAX — максимально допустимая
при выходе буфер заполнен данными следующим образом:
¦max¦len¦ T E X T 0dH LEN — действительная длина данных
символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter).
Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. последний символ в буфере — всегда CR (который не засчитан в байте длины). символы в буфере (включая LEN) в момент вызова используются как «шаблон». В процессе ввода действительны обычные клавиши редакти рования: Esc выдает «\» и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает «@» и сохраняет текущую строку как шаблон, и т.д. большинство расширенных кодов ASCII игнорируются. при распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).
Fn 25H: установить вектор прерывания
Вход
- AH = 25H
- AL = номер прерывания
- DS:DX = вектор прерывания: адрес программы обработки прерывания
Выход
Описание:
устанавливает значение элемента таблицы векторов прерываний для прерывания с номером AL равным DS:DX. это равносильно записи 4-байтового адреса в 0000:(AL*4), но, в отличие от прямой записи, DOS здесь знает, что вы делаете, и гарантирует, что в момент записи прерывания будут заблокированы.
Предупреждение:
Не забудьте восстановить DS (если необходимо) после этого вызова.
Fn 35H: дать вектор прерывания
Вход
- AH = 35H
- AL = номер прерывания (00H до 0ffH)
Выход
- ES:BX = адрес обработчика прерывания
Описание:
возвращает значение вектора прерывания для INT (AL); то есть, загружает в BX 0000:[AL*4], а в ES — 0000:[(AL*4)+2].
Предупреждение:
Эта функция изменяет сегментный регистр ES.
Fn 27H: читать произвольный блок файла
Вход
- AH = 27H
- DS:DX = адрес открытого FCB
- CX = число считываемых записей
Выход
- AL = 0 если чтение успешно и DTA заполнена данными
- AL = 1 если достигнут конец файла (EOF) и данные не считаны
- AL = 2 если DTA + FCB (RecSize * CX) выходит за границу сегмента
- AL = 3 если EOF и считана усеченная порция (дополнена нулями)
- CX = действительное число считанных записей
Описание:
Читает несколько записей из файла, начиная с файлового адреса, специфицированного полем RandomRec в FCB. Помещает данные в память, начиная с адреса DTA. число считанных байт = FCB RecSize*CX. Поля RandomRec, CurBlk и CurRec корректируются, чтобы указывать на следующую запись (первую запись за прочитанными).
Fn 31H: завершиться и остаться резидентным — KEEP
Вход
- AH = 31H
- AL = код выхода
- DX = объем памяти, оставляемой резидентной, в параграфах
Выход
Описание:
выходит в родительский процесс, сохраняя код выхода в AL. код выхода можно получить через функцию 4dH Wait. DOS устанавливает начальное распределение памяти, как специфицировано в DX, и возвращает управление родительскому процессу, оставляя указанную память резидентной (число байт = DX * 16). Эта функция перекрывает функцию INT 27H, которая не возвращает код выхода и неспособна установить резидентную программу, большую 64K.
Ассемблер
Прерывание 21h: функции DOS для работы с буфером клавиатуры
Различные служебные функции DOS для работы с буфером клавиатуры (функции 01h, 06h, 07h, 08h, 0Ah, 0Bh и 0Ch) классифицируются прежде всего по трем критериям: ожидают ли они ввода или же, когда символ не получен, сообщают, что ввода нет; выдают ли они на экран дисплея эхо (введенный символ); и реагирует ли функция на ввод стандартного символа прерывания во время ее исполнения. (Напомним, что нажатие комбинации клавиш Ctrl-Break или Ctrl-C рассматривается как прерывание ограниченным числом стандартных функций DOS. Однако, начиная с версии 2.00, в DOS введена команда BREAK ON, которая дает указание DOS реагировать на ввод символа прерывания при всех обстоятельствах.)
Все функции ввода с клавиатуры получают введенный символ из буфера клавиатуры, размещенного в памяти компьютера, а не непосредственно из порта 60h интерфейса клавиатуры (из порта 60h скан-коды считываются прерыванием 09h, переводятся в коды символов и помещаются в буфер клавиатуры).
Функция 1 прерывания 21h: ввод символа с эхопечатью
Функция 01h ждет появления символа в буфере клавиатуры со стандартного устройства ввода и после приема символа помещает его в регистр AL. Другие функции, относящиеся к вводу символов с клавиатуры: 06h, 07h и 08h.
Примечание. В первой версии DOS стандартным устройством ввода всегда является клавиатура, а стандартным устройством вывода — экран дисплея. В последующих версиях DOS имеется возможность переадресации стандартного ввода и вывода на другие устройства, а также в файлы. DOS обрабатывает символы, поступающие от стандартного устройства ввода, одинаковым образом независимо от того, является ли их источником реальное устройство (такое, как клавиатура) или поток символов, переадресованный из файла.
Работа функции 01h происходит следующим образом. Нажатие клавиши, соответствующей одному из символов кода ASCII, приводит к записи соответствующего байта в регистр AL и немедленной выдаче символа данной функцией на экран (в позицию курсора). Нажатие клавиши, формирующей сигнал, не относящийся к оду ASCII, приводит к формированию двух байтов, которые могут быть получены путем двух последовательных обращений к данной функции.
Обычно функция 01h применяется для проверки принадлежности символа, соответствующего нажатой клавише, коду ASCII. Для этого производится проверка регистра AL. Если AL не равно 00h, то это символ кода ASCII. Если же AL=00h, то вы имеете дело с символом, не относящимся к коду ASCII; в этом случае следует повторить обращение к данной функции для получения псевдокода, соответствующего специальному действию клавиши. Как и в случае применения других средств DOS, предназначенных для ввода символов с клавиатуры, при использовании данной функции развернутый код символов набора ASCII оказывается недоступным, даже если соответствующие средства обслуживания клавиатуры системы ROM BIOS позволяют осуществить доступ к нему.
Функция 6 прерывания 21h: непосредственный ввод
и вывод с консоли
Функция 06h — это универсальная функция, объединяющая операции ввода с клавиатуры и вывода на дисплей. В версиях DOS, начиная со второй и выше, эта функция, как и другие, действует по отношению уже не к клавиатуре и дисплею, а к стандартным устройствам ввода и вывода (в качестве которых по умолчанию принимаются клавиатура и дисплей).
При реализации данной функции регистр AL используется для ввода, а регистр DL — для вывода. Если при вызове функции 06h в регистре DL находится значение FFh (в десятичной нотации 255), то при нажатии какой-либо клавиши эта функция поместит соответствующий ASCII-код в регистр AL и сбросит нулевой флаг; при отсутствии нажатия клавиши она установит нулевой флаг.
Если же вызвать функцию 06h при любом другом значении регистра DL, то будет выполнен вывод символа, соответствующего данному значению, на стандартное устройство вывода.
Функция 06h не ожидает ввода символа с клавиатуры и не осуществляет его эхопечати на экране. Кроме того, функция 06h не воспринимает сочетание клавиш Ctrl-C как прерывание программы (при использовании данного сочетания она помещает в регистр AL значение 03h, т.е. соответствующий данному значению ASCII-код).
Функция 7 прерывания 21h: непосредственный ввод
с консоли без эхопечати
Функция 07h ожидает ввода символа со стандартного устройства ввода и после ввода символа помещает его в регистр AL. Она не осуществляет эхопечати символа на экране и не воспринимает сочетание клавиш Ctrl-C как прерывание программы.
Функция 07h действует точно так же, как функция 01h: нажатие клавиши, относящейся к коду ASCII, приводит к немедленному занесению в регистр AL соответствующего байта; нажатие клавиши, не относящейся к коду ASCII, приводит к формированию двух байтов, которые могут быть получены двумя последовательными обращениями к функции 07h.
Функция 8 прерывания 21h:
ввод с консоли без эхопечати
Функция 08h ожидает ввода символа, не осуществляя эхопечати и прерывает программу при нажатии Ctrl-C.
Эта функция идентична функции 01h, за исключением того, что она не выводит введенный символ на экран дисплея (или стандартное устройство вывода).
Для более полного понимания особенностей данной функции обратитесь к описанию функции 01h. Сравните данную функцию с функциями 01h, 06h и 07h. Если вы хотите использовать функцию 08h, но не желаете ждать ввода символа, изучите функцию 0Bh, которая сообщает о готовности ввода. Изучите также функцию 0Ch, которая является модификацией данной функции.
Создаем вирус и антивирус (34 стр.)
При DL=0FFh выполняет ввод с консоли «Без ожидания», возвращая включенный флаг нуля ZF, если на консоли нет готового символа. Если символ готов, сбрасывает флаг ZF и возвращает считанный символ в AL. Если DL не равен 0FFh, то DL направляется на стандартный вывод.
DOS, функция 07h Нефильтрующий консольный ввод без эха
Выход: AL – символ, полученный через стандартный ввод
Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не проверяет на Ctrl-Break, BackSpace и другие.
Для ввода расширенного символа ASCII должна быть вызвана дважды. Для проверки статуса используется функция DOS 0Bh (чтобы не ожидать нажатия клавиши).
DOS, функция 08h Консольный ввод без эха
Выход: AL – символ, полученный через стандартный ввод
Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23h.
Для ввода расширенного символа ASCII должна быть вызвана дважды.
DOS, функция 09h Запись строки на стандартный вывод
DS:DX – адрес строки, заканчивающейся символом «$» (ASCII 24h)
Строка, исключая завершающий ее символ «$», посылается на стандартный вывод. Символы Backspace обрабатываются как в функции 02h (вывод на дисплей). Чтобы перейти на новую строку, обычно включают в текст пару CR/LF (ASCII 0Dh и ASCII 0Ah). Строки, содержащие «$», можно передать на стандартное устройство вывода с помощью функции 40h (BX=0).
DOS, функция 0Ah Ввод строки в буфер
DS:DX – адрес входного буфера (Таблица Б-1)
Таблица Б-1. Формат входного буфера
Буфер содержит введенные данные, в конце – символ CR (ASCII 0Dh)
DOS, функция 0Bh Проверка статуса ввода
Выход: AL=FFh, если символ доступен со стандартного ввода AL=00h, если нет доступного символа
Описание. Проверяет состояние стандартного ввода. При распознавании Ctrl-Break выполняется INT 23h.
Используется перед функциями 01h, 07h и 08h, чтобы избежать ожидания нажатия клавиши.
Эта функция дает простой неразрушающий способ проверки Ctrl-Break в процессе длинных вычислений или другой обработки, обычно не требующей ввода. Это позволяет снимать счет по нажатию Ctrl-Break.
DOS, функция 0Ch Ввод с очисткой
AL – номер функции ввода DOS:
AL=01h – ввод с клавиатуры
AL=06h – ввод с консоли
AL=07h – нефильтрующий без эха
AL=08h – ввод без эха
AL=0Ah – буферизованный ввод
Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. Это заставляет систему ожидать ввод очередного символа.
DOS, функция 0Dh Сброс диска
Сбрасывает диск (записывает на диск все файловые буферы). Файл, размер которого изменился, должен быть предварительно закрыт (при помощи функций 10h или 3Eh).
DOS, функция 0Eh Установить текущий диск DOS
DL – номер диска (0 – A, 1 – B и так далее), который становится текущим
Выход: AL – общее число дисководов в системе
Описание. Диск, указанный в DL, становится текущим. Проверка: используется функция 19h (дать текущий диск). В регистре AL возвращается число дисководов всех типов, включая жесткие диски и «логические» диски (как диск B: системе с одним гибким диском).
AL имеет то же значение, что и LASTDRIVE, указанное в файле CONFIG.SYS, и по умолчанию равно 5.
DOS, функция 0Fh Открыть файл через FCB
DS:DX – адрес неоткрытого FCB (Таблица Б-2)
Таблица Б-2. Формат FCB
AL=00h, если функция выполнена успешно (FCB заполнен)
AL=FFh, если файл не найден или доступ к файлу не разрешен
Файл, описываемый неоткрытым FCB, должен существовать в текущем оглавлении на диске, специфицированном в FCB (0 – текущий, 1 – A, 2 – B и так далее). Если файл не существует, возвращается AL=0FFh. Файл открывается в режиме совместимости. Если поле «Номер диска» в FCB равно нулю в момент вызова, то оно заполняется номером текущего дисковода (1 – A, 2 – B и так далее). Поле FCB «Номер текущего блока» устанавливается в ноль. Поле FCB «Размер логической записи» устанавливается в 80h. Поля даты и размера файла в FCB устанавливаются из оглавления.
DOS, функция 10h Закрыть файл через FCB
DS:DX – адрес открытого FCB (Таблица Б-2)
AL=00h, если функция выполнена успешно
AL=FFh, если файл не найден там, где он находился при открытии с помощью функции 0Fh
Закрывает файл, открытый функцией 0Fh. Файл должен находиться на своем первоначальном месте в текущем оглавлении диска, на котором он был открыт. Если файл найден, оглавление обновляется, файловые буфера сбрасываются и возвращается AL=00h. Если файл не найден, оглавление не обновляется и возвращается AL=FFh.
DOS, функция 11h Найти первый совпадающий файл через FCB
DS:DX – адрес неоткрытого FCB (Таблица Б-2)
AL=00h, если подходящее имя найдено
AL=FFh, если подходящего имени нет
В текущем оглавлении DOS происходит поиск файлов с именем, соответствующим заданному шаблону. При неудаче возвращается AL=0FFh. Если имя найдено, AL очищается, в первый байт DTA помещается номер дисковода (A – 1, B – 2 и так далее), а в следующие 32 байта помещается элемент оглавления для найденного файла.
Можно использовать при вызове расширенный FCB, чтобы выбирать файлы с указанными атрибутами. В этом случае в DTA помещаются: байт FFh, 7 байт нулей, номер диска и элемент оглавления.
DOS, функция 12h Найти следующий совпадающий файл через FCB
DS:DX – адрес неоткрытого FCB (Таблица Б-2)
AL=00h, если подходящее имя найдено
DTA заполнен AL=FFh, если подходящего имени нет
Используется после вызова функции 11h (Найти первый совпадающий файл через FCB) с обобщенным именем файла. Каждый последующий вызов заполняет DTA очередным подходящим элементом оглавления и возвращает AL=00h. Если подходящих имен больше нет, возвращается AL=FFh.
Резервируемая область в FCB сохраняет информацию, необходимую для продолжения поиска. Поэтому не стоит открывать и изменять FCB между вызовами.
DOS, функция 13h Удалить файл через FCB
DS:DX – адрес неоткрытого FCB (Таблица Б-2)
AL=00h, если функция выполнена успешно
AL=FFh, если файл не найден или доступ к файлу не разрешен
Эта функция удаляет все подходящие файлы в текущем оглавлении указанного диска согласно спецификации в FCB. Если подходящие файлы не найдены или если доступ отвергнут (как при попытке удалить файл с атрибутом Read-Only), функция возвращает в регистре AL значение FFh.
DOS, функция 14h Последовательное чтение из файла через FCB
DS:DX – адрес открытого FCB (Таблица Б-2)
AL=00h, если чтение было успешным и DTA содержит данные
AL=01h, если достигнут конец файла (EOF) и данные не считаны
AL=02h, если произошел выход за сегмент (чтения не было)
AL=03h, если EOF и считана усеченная запись (дополнена нулями)
Функция читает файл, специфицированный в FCB. Затем соответственно увеличивает значения полей в FCB.
Перед началом последовательной обработки файла нужно сбрасывать CurRec в ноль, так как функция 0Fh не инициализирует это поле.
DOS, функция 15h Последовательная запись в файл через FCB
DS:DX – адрес открытого FCB (Таблица Б-2)
AL=00h, если запись была успешной
AL=01h, если ошибка переполнения диска (данные не записаны)
AL=02h, если произошел выход за сегмент (записи не было)
Функция записывает файл, специфицированный в FCB. Затем соответственно увеличивает значения полей в FCB.
Перед началом последовательной обработки файла нужно сбрасывать «Номер текщей записи» в ноль, так как функция 0Fh не инициализирует это поле.
DOS буферизует данные, записывая полный сектор за один раз.
DOS, функция 16h Создание файла через FCB
DS:DX – адрес неоткрытого FCB (Таблица Б-2)
Функция DOS 06h — Считать символ из STDIN без эха, без ожидания и без проверки на Ctrl-Break
Читайте также:
|
Ввод: | АН = 07h DL = 0FFh |
Вывод: | ZF = 1, если не была нажата клавиша, и AL = 00 ZF = 0, если клавиша была нажата. В этом случае AL = код символа |
Кроме перечисленных функций могут потребоваться и некоторые служебные функции 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 очищает буфер клавиатуры, так что следующая функция чтения символа будет ждать ввода с клавиатуры, а не использовать нажатый ранее и еще не обработанный символ. Например, именно эта функция используется для считывания ответа на вопрос «Уверен ли пользователь в том, что он хочет отформатировать диск?».
DOS предоставляет несколько функций для вывода текста на экран.
Функция DOS 02h — Записать символ в STDOUT с проверкой на Ctrl-Break
Ввод: | АН = 02h DL = ASCII-код символа |
Вывод: | Никакого, согласно документации, но на самом деле: AL = код последнего записанного символа (равен DL, кроме случая, когда DL = 09h (табуляция), тогда в AL возвращается 20h). |
Эта функция при выводе на экран обрабатывает некоторые управляющие символы:
— символ BEL (07h) – выводит звуковой сигнал;
— символ BS (08h) – двигает курсор влево на одну позицию;
— символ НТ (09h) – заменяется на несколько пробелов;
— символ LF (0Ah) – опускает курсор на одну позицию вниз;
— символ CR (0Dh) – приводит к переходу на начало текущей строки.
Если в ходе работы этой функции была нажата комбинация клавиш Ctrl-Break, вызывается прерывание 23h, которое по умолчанию осуществляет выход из программы.
Функция DOS 06h — Записать символ в STDOUT без проверки на Ctrl-Break
Ввод: | АН = 06h DL = ASCII-код символа (кроме FFh) |
Вывод: | Никакого, согласно документации, но на самом деле: AL = код записанного символа (копия DL) |
Эта функция не обрабатывает управляющие символы (CR, LF, HT и BS выполняют свои функции при выводе на экран, но сохраняются при перенаправлении вывода в файл) и не проверяет нажатие Ctrl-Break. Можно заменить в программе dosoutl.asm команду MOV АН,2 на MOV АН,6 и перекомпилировать этот пример, чтобы получить более полную таблицу символов.
Дата добавления: 2015-01-30 ; просмотров: 14 | Нарушение авторских прав
Проверка вводимого значения
Windows Batch file | ||||||||
08.10.2020, 15:01 | ||||||||
Проверка вводимого текста в bat Присвоение переменной значения, вводимого вручную Проверка значения параметра реестра Проверка вводимого значения в поле Дата 2 КлавиатураВ этом разделе мы подробно рассмотрим одно из важнейших устройств персонального компьютера — клавиатуру. Практически ни одна программа не обходится без обращения к клавиатуре. Программа может использовать клавиатуру по-разному. Она может задерживать свое выполнение до тех пор, пока пользователь не введет какое-нибудь число или пока не нажмет какую-нибудь клавишу. Выполняя некоторую работу, программа может периодически проверять, была ли нажата клавиша, изменяющая режим работы программы. Резидентные программы могут активизироваться, когда пользователь нажимает заранее определенную комбинацию. Можно использовать прерывание, вырабатываемое клавиатурой, например, для завершения работы программы. Мы расскажем о работе с клавиатурой в среде MS-DOS на разных уровнях — от использования клавиатурных портов ввода/вывода до средств, предоставляемых стандартными библиотеками трансляторов C. Какой уровень вам следует выбрать, зависит от решаемой задачи. Единственное, что можно порекомендовать — это использовать по возможности средства высокого уровня. Если ваша программа обращается к клавиатуре через порты ввода/вывода, ее работоспособность может оказаться зависимой от типа клавиатуры и от модели компьютера. Что же касается методики работы с клавиатурой в операционных системах Microsoft Windows, то она была описана в 11 томе «Библиотеки системного программиста», который называется «Операционная система Microsoft Windows для программиста». Как работает клавиатураКлавиатура выполнена, как правило, в виде отдельного устройства, подключаемого к компьютеру тонким кабелем. Малогабаритные блокнотные компьютеры содержат встроенную клавиатуру. Что же находится внутри клавиатуры? Оказывается, там есть компьютер! Только этот компьютер состоит из одной микросхемы и выполняет специализированные функции. Когда вы нажимаете на клавиши, он посылает номер нажатой клавиши в центральный компьютер. Клавиатурная матрицаЕсли рассмотреть сильно упрощенную принципиальную схему клавиатуры, представленную на рисунке, можно заметить, что все клавиши находятся в узлах матрицы (рис. 2.1). Рис.2.1. Упрощенная схема клавиатуры Все горизонтальные линии матрицы подключены через резисторы к источнику питания +5 В. Клавиатурный компьютер имеет два порта — выходной и входной. Входной порт подключен к горизонтальным линиям матрицы (X0-X4), а выходной — к вертикальным (Y0-Y5). Устанавливая по очереди на каждой из вертикальных линий уровень напряжения, соответствующий логическому нулю, клавиатурный компьютер опрашивает состояние горизонтальных линий. Если ни одна клавиша не нажата, уровень напряжения на всех горизонтальных линиях соответствует логической единице (так как все эти линии подключены к источнику питания +5 В через резисторы). Если вы нажмете на какую-либо клавишу, то соответствующая вертикальная и горизонтальная линии окажутся замкнутыми. Когда на этой вертикальной линии процессор установит значение логического нуля, то уровень напряжения на горизонтальной линии также будет соответствовать логическому нулю. Как только на одной из горизонтальных линий появится уровень логического нуля, клавиатурный процессор фиксирует нажатие на клавишу. Он посылает в центральный компьютер запрос на прерывание и номер клавиши в матрице. Аналогичные действия выполняются и тогда, когда вы отпускаете нажатую ранее клавишу. Скан-код клавишиНомер клавиши, посылаемый клавиатурным процессором, однозначно зависит от схемы клавиатурной матрицы, но не от обозначений, нанесенных на поверхность клавиш. Этот номер называется скан-кодом (Scan Code). Слово scan («сканирование»), подчеркивает тот факт, что клавиатурный компьютер сканирует клавиатуру для поиска нажатой клавиши. Код ASCII нажатой клавишиОбычно программе нужен не порядковый номер нажатой клавиши, а код, соответствующий обозначению на этой клавише (код ASCII). Код ASCII не связан напрямую со скан-кодом, так как одной и той же клавише могут соответствовать несколько значений кода ASCII в зависимости от состояния других клавиш. Например, клавиша с обозначением «1» используется еще и для ввода символа «!» (если она была нажата вместе с клавишей ). Поэтому все преобразования скан-кода в код ASCII выполняются программно. Как правило, в операционной системе MS-DOS эти преобразования выполняют модули BIOS. Для использования символов кириллицы эти модули расширяются клавиатурными драйверами, как входящими в состав локализованных версий MS-DOS, так и созданными в виде отдельных программ. Режим автоповтораЕсли нажать на клавишу и не отпускать ее, клавиатура перейдет в режим автоповтора. При этом в компьютер автоматически через некоторый период времени, называемый периодом автоповтора, посылается код нажатой клавиши. Режим автоповтора облегчает ввод с клавиатуры большого количества одинаковых символов. Следует отметить, что клавиатура содержит внутренний 16-байтовый буфер, через который она осуществляет обмен данными с компьютером. Типы клавиатурДо недавнего времени существовали три различных типа клавиатуры. Это клавиатура для компьютеров IBM PC/XT, 84-клавишная клавиатура для IBM PC/AT и 101-клавишная (расширенная) клавиатура для IBM PC/AT. Некоторые клавиатуры имеют переключатель режима работы (XT/AT), расположенный на нижней крышке. Он должен быть установлен в правильное положение. После того как операционная система Microsoft Windows получила широкое распространение, специально для нее был создан новый тип клавиатуры. К обычной клавиатуре типа IBM PC/AT были добавлены две кнопки, первая из которых дублирует вызов меню Start, выполняемый при помощи левой клавиши мыши, а вторая – вызов того же меню при помощи правой клавиши мыши. Порты для работы с клавиатуройНазначение портов, предназначенных для работы с клавиатурой, зависят от типа компьютера. Компьютер IBM PC/XTДля работы с клавиатурой типа IBM PC/XT используются порты с адресами 60h и 61h. Порт 60h доступен только для чтения. После выполнения этой операции он содержит скан-код последней нажатой клавиши. Порт 61h доступен как для чтения, так и для записи. Он управляет не только клавиатурой, но и другими устройствами компьютера, например, работой встроенного динамика. Если в старший бит порта 61h записать значение 1, клавиатура будет заблокирована, если 0 — разблокирована. Так как порт 61h управляет не только клавиатурой, при изменении содержимого старшего бита необходимо сохранить состояние остальных битов этого порта. Для этого можно сначала выполнить чтение содержимого порта в регистр, изменить состояние старшего бита, затем выполнить запись нового значения в порт: Современные компьютерыСовременные компьютеры позволяют управлять скоростными характеристиками клавиатуры, а также зажигать или гасить светодиоды Scroll Lock, Num Lock и Caps Lock, расположенные на лицевой панели клавиатуры. Для расширенного управления клавиатурой применяется порт 60h в режиме записи. Этот порт служит для управления подчиненным процессором Intel 8042, ответственным за обмен данными с клавиатурным компьютером, или его аналогом, установленным на системной плате компьютера. При использовании порта 60h на запись программа дополнительно получает следующие возможности: · установка времени ожидания перед переходом клавиатуры в режим автоповтора; · установка периода генерации скан-кода в режиме автоповтора; · управление светодиодами, расположенными на лицевой панели клавиатуры. Процессор 8042 обслуживает не только клавиатуру, но и другие системы компьютера. Через порт 64h, например, выполняется сброс (отключение) процессора 80286 для возврата из защищенного режима работы в реальный. Подробности об этом вы можете узнать из 6 тома «Библиотеки системного программиста», который называется «Защищенный режим процессоров Intel 80286/80386/80486». Перед тем как посылать команду процессору 8042, необходимо убедиться в том, что его внутренняя очередь команд пуста. Это можно сделать, прочитав слово состояния 8042 из порта с адресом 64h. Бит с номером 1 должен быть равен нулю. Приведем фрагмент программы, составленной на языке ассемблера, проверяющий состояние очереди команд процессора 8042: После того, как программа дождется готовности процессора 8042, она может послать ему команду, записав ее в порт с адресом 60h: Некоторые команды состоят более чем из одного байта. Второй и следующие байты таких команд необходимо записывать в порт 60h, предварительно убедившись в готовности процессора 8042 с помощью приведенной выше последовательности команд. В большинстве случаев можно также использовать простую временную задержку: Мы приведем формат двух команд процессора 8042, имеющих отношение к работе с клавиатурой — команду установки задержки и периода автоповтора и команду управления светодиодами, расположенными на клавиатуре. Для установки характеристик режима автоповтора в порт 60h необходимо записать код команды 0F3h, затем байт, определяющий характеристики режима. Ниже вы найдете описание полей байта режима автоповтора: Период автоповтора, который определяет количество посылок скан-кода, генерируемых процессором клавиатуры в одну секунду. Можно использовать не только те значения, которые приведены ниже, но и промежуточные, например, 9 или 15h. Задержка включения режима автоповтора, mc: Зарезервировано и должно быть равно нулю Первоначально при инициализации системы BIOS устанавливает период задержки для включения режима автоповтора равным 500 мс при периоде автоповтора, равным 10 повторам в секунду. Если это слишком медленно для вас, вы можете установить другие значения. Для управления светодиодами, расположенными на лицевой панели клавиатуры, используйте команду 0EDh. Вслед за этой командой в порт 60h необходимо записать байт, имеющий следующий формат: 1 – включить светодиод Scroll Lock; 0 – выключить светдиод Scroll Lock 1 – включить светодиод Num Lock; 0 – выключить светодиод Num Lock 1 – включить светодиод Caps Lock; 0 – включить светодиод Caps Lock Программа KBDLEDПриведем пример простейшей программы KBDLED, управляющей светодиодами, расположенными на лицевой панели клавиатуры (листинг 2.1). Такое управление может выполняться только при использовании порта 60h, так как BIOS не содержит никаких подходящих для этого функций. Наша программа после запуска включит все светодиоды и будет ожидать, пока вы не нажмете любую клавишу. Затем программа выключит светодиоды. Заметим, что программа KBDLED может не работать на виртуальной машине DOS, создаваемой, например, в операционной системе Microsoft Windows NT. Листинг 2.1. Файл kbdled\kbdled.c Аппаратное прерывание клавиатурыКлавиатура подключена к линии прерывания IRQ1. Этой линии соответствует прерывание INT 09h. Клавиатурное прерывание обслуживается BIOS, однако драйверы клавиатуры и резидентные программы могут организовывать дополнительную обработку прерывания INT 09h. Для этого может быть использована цепочка обработчиков прерывания. Стандартный обработчик прерывания INT 09hКак работает стандартный обработчик клавиатурного прерывания, входящий в состав BIOS? Этот обработчик выполняет следующие действия: · читает из порта 60h скан-код нажатой клавиши; · записывает вычисленное по скан-коду значение кода ASCII нажатой клавиши в специальный буфер клавиатуры, расположенный в области данных BIOS; · устанавливает в единицу бит 7 порта 61h, разрешая дальнейшую работу клавиатуры; · возвращает этот бит в исходное состояние; · записывает в порт 20h значение 20h для правильного завершения обработки аппаратного прерывания. Обработчик прерывания INT 09h не просто записывает значение кода ASCII в буфер клавиатуры, но также выполняет и другие действия. Например, он дополнительно отслеживает нажатие пользователем таких комбинаций клавиш, как , обрабатывает специальные клавиши и . При вычислении кода ASCII нажатой клавиши учитывается состояние клавиш и . Буфер клавиатурыБуфер клавиатуры имеет длину 32 байта и расположен в компьютере IBM PC/XT по адресу 0000h:041Eh. В компьютерах моделей IBM PC/AT и IBM PS/2 расположение клавиатурного буфера задается содержимым двух слов памяти с адресами 0000h:0480h (смещение адреса начала буфера) и 0000h:0482h (смещение конца буфера). Обычно эти ячейки памяти содержат значения, соответственно, 001Eh и 003Eh. Так как смещения заданы относительно сегментного адреса 0040h, то стандартное расположение клавиатурного буфера в IBM PC/AT и IBM PS/2 соответствует его расположению в IBM PC/XT. Буфер клавиатуры организован циклически. Это означает, что при его переполнении самые старые значения будут потеряны. Две ячейки памяти, находящиеся в области данных BIOS с адресами 0000h:041Ah и 0000h:041Ch содержат, соответственно, указатели на начало и конец буфера. Если значения этих указателей равны друг другу, буфер пуст. Заметим, что вы можете удалить все символы из буфера клавиатуры, установив оба указателя на начало буфера. Однако есть более предпочтительный способ с использованием прерывания BIOS INT 16h, функции которого мы опишем позже в этой главе. Указателями на начало и конец клавиатурного буфера обычно управляют обработчики прерываний INT 09h и INT 16h. Программа извлекает из буфера коды нажатых клавиш, используя различные функции прерывания INT 16h. При переполнении внутреннего буфера клавиатуры или буфера, расположенного в области данных BIOS программа-обработчик прерывания INT 09h генерирует звуковой сигнал. В программах MS-DOS у вас едва ли появится необходимость непосредственного манипулирования содержимым буфера клавиатуры — вы можете использовать прерывание BIOS INT 16h для выполнения практически всех клавиатурных операций. Переключающие клавишиПомимо управления содержимым буфера клавиатуры, обработчик прерывания INT 09h отслеживает так называемые переключающие клавиши — , , , . Состояние этих клавиш записывается в область данных BIOS в два байта с адресами 0000h:0417h и 0000h:0418h. Лабораторная работа №6 Ввод информации с клавиатуры терминала
|
Лабораторная работа №6 Ввод информации с клавиатуры терминала Для уверенной работы с машиной полезно понимать, каким образом вводятся, куда попадают и как обрабатываются символы, вводимые с клавиатуры. Процесс взаимодействия системы с клавиатурой продемонстрирован на рис. Адрес ПОП — вектора прерывания 09h (ячейки 00:24h и 00:26h) Работой клавиатуры управляет специальная электронная схема — контроллер клавиатуры. В его функции входит распознавание нажатой клавиши и помещение закрепленного за ней кода в свой выходной регистр (порт), обычно с номером 60h. Код клавиши, поступающий в порт, называется скен-кодом и является, по существу, порядковым номером клавший, хотя последовательность скен-кодов не всегда совпадает с порядком расположения клавиш на клавиатуре. При этом каждой клавише присвоены как бы два скен-кода, отличающиеся друг от друга на 80h. Один скен-код (меньший, код нажатия) засылается контроллером в порт 60h при нажатии клавиши, другой (больший, код отпускания) — при ее отпускании. Скен-код однозначно указывает на нажатую клавишу, однако по нему нельзя определить, работает ли пользователь на нижнем или верхнем регистре, а также вводит ли он латинские или русские буквы. С другой стороны, скен-коды присвоены всем клавишам клавиатуры, в том числе управляющим клавишам , , , и др. Таким образом, очевидно, что определение введенного символа должно включать в себя не только считывание скен-кода нажатой клавиши, но и выяснение того, не были ли перед этим нажаты, например, клавиши (верхний регистр) или (фиксация верхнего регистра). Всем этим анализом занимается программа обработки прерываний от клавиатуры. Нажатие (а также и отпускание) любой клавиши вызывает сигнал аппаратного (внешнего) прерывания, заставляющий процессор прервать выполняемую программу и перейти на программу обработки прерывания (ПОП) от клавиатуры. Эта программа хранится по фиксированному адресу в постоянном запоминающем устройстве BIOS, являясь, таким образом, элементом «встроенного», или «зашитого» программного обеспечения. Процессор вместе с сигналом прерывания получает еще и тип прерывания, или его номер. За клавиатурой закреплен номер 09h. Адрес программы обработки прерываний от клавиатуры располагается; таким образом, и векторе 09h, занимающем слова с адресами 24h и 26 h (36-38 ячейки памяти). Получив тип прерывания и определив по нему адрес вектора, процессор извлекает из вектора адрес программы обработки прерываний и осуществляет переход на ее выполнение. Поскольку программа обработки прерываний от клавиатуры вызывается через вектор 09h, ее часто называют программой INT 09h (INT — от английского Interrupt, прерывание). Программа INT 09h, помимо порта 60h, работает еще с двумя областями оперативной памяти: кольцевым буфером ввода, располагаемым по адресам от 40h:1Eh до 40h:3Dh, куда, в конце концов, помещаются коды ASCII нажатых клавиш, и словом состояния (словом флагов) клавиатуры, находящимся по адресу 40h:17h, где фиксируется состояние управляющих клавиш ( , , и др.). Программа INT 09h, получив управление в результате прерывания от клавиатуры, считывает из порта 60h скен-код и анализирует его значение. Если скен-код принадлежит одной из управляющих клавиш, и, к тому же, представляет собой код нажатия, в слове флагов клавиатуры устанавливается бит (флаг), соответствующий нажатой клавише. Например, при нажатии правой клавиши в слове флагов устанавливается бит 0, при нажатии левой клавиши — бит 1, при нажатии любой клавиши -бит 2, а при нажатии (тоже любой) — бит 3. Биты флагов сохраняют свое состояние пока клавиши (по одиночке или в любых комбинациях) остаются нажатыми. Если управляющая клавиша отпускается, программа INT 09h получает скен-код отпускания и сбрасывает соответствующий бит в слове флагов. Кроме состояния указанных клавиш, в слове флагов фиксируются еще режимы , , и , а в 101-клавишной клавиатуре на компьютерах РС/АТ также состояния клавиш , -левая, -левая и режим паузы ( / ). При нажатии любой другой клавиши программа INT 09h считывает из порта 60h ее скен-код нажатия и по таблице трансляции скен-кодов в коды ASCII формирует двухбайтовый код, старший байт которого содержит скен-код, а младший — код ASCII. При этом если скен-код характеризует клавишу, то код ASCII определяет закрепленный за ней символ. Поскольку за каждой клавишей закреплено, как правило, не менее двух символов («а»и «А», «1» и «!», «2» и»@» и т.д.), то каждому скен-коду соответствуют, как минимум, два кода ASCII. В процессе трансляции программа INT 09h анализирует состояние флагов, так что если нажата, например, клавиша Q (скен-код 10h, код ASCII буквы Q — 51 h, а буквы q — 71h), то формируется двухбайтовый код 1071h, но если клавиша Q нажата при нажатой клавише (смена регистра), то результат трансляции составит 105lh. Тот же код 105lh получится, если при нажатии клавиши Q был включен режим (заглавные буквы), однако при включенном режиме и нажатой клавише образуется код 107lh, поскольку в такой ситуации клавиша на время нажатия переводит клавиатуру в режим нижнего регистра (строчные буквы). Полученный в результате трансляции двухбайтовый код засылается программой INT 09h в кольцевой буфер ввода, который служит для синхронизации процессов ввода данных с клавиатуры и приема их выполняемой компьютером программой. Объем кольцевого буфера составляет 15 слов, при этом дисциплина его обслуживания такова, что коды символов извлекаются из него в том же порядке, в каком они в него поступали. За состоянием буфера следят два указателя. В хвостовом указателе (слово по адресу 40:lCh) хранится адрес первой свободной ячейки, в головном указателе (40: lAh) — адрес самого старого кода, принятого с клавиатуры и еще не востребованного программой. В начале работы, когда буфер пуст, оба указателя — и хвостовой, и головной, указывают на первую ячейку буфера. Программа INT 09h, сформировав двухбайтовый код, помещает его в буфер по адресу, находящемуся в хвостовом указателе. после этого этот адрес увеличивается на 2, указывая опять на первую свободную ячейку. Каждое последующее нажатие на какую-либо клавишу добавляет в буфер очередной двухбайтовый код и смещает хвостовой указатель. Выполняемая программа, желая получить код нажатой клавиши, должна вызвать прерывание INT 16h, которое активизирует драйвер клавиатуры — BIOS. Драйвер считывает из кольцевого буфера содержимое ячейки, адрес которой находится в головном указателе, и увеличивает этот адрес на 2. Таким образом, программный запрос на ввод с клавиатуры фактически выполняет прием кода не с клавиатуры, а из кольцевого буфера. Хвостовой указатель, перемещаясь по буферу в процессе занесения в него кодов, доходит, наконец, до конца буфера (адрес40h:ЗСh). В этом случае при поступлении очередного кода адрес в указателе не увеличивается, а, наоборот, уменьшается на длину буфера. Тем самым указатель возвращается в начало буфера, после чего продолжает перемещаться по буферу до его конца, опять возвращается в начало и так далее по кольцу. Аналогичные манипуляции выполняются и с головным указателем. Равенство адресов в обоих указателях свидетельствует о том. что буфер пуст. Если при этом программа вызвала прерывание INT 16h, то драйвер клавиатуры будет ждать поступления кода в буфер, после чего он будет передан в программу. Если же хвостовой указатель, перемещаясь по буферу в процессе его заполнения, подошел к головному указателю «с обратной стороны» (это произойдет, если оператор нажимает на клавиши, а программа не выполняет запросы к драйверу клавиатуры), прием новых кодов блокируется, а нажатие на клавиши возбуждает предупреждающие звуковые сигналы. Если компьютер находится в пассивном состоянии ожидания команд DOS с клавиатуры, то за состоянием кольцевого буфера ввода следит командный процессор COMMAND.COM. Как только в буфере появляется код символа, командный процессор с помощью соответствующих системных программ переносит его в свой внутренний буфер командной строки, очищая при этом кольцевой буфер ввода, а также выводит символ на экран, организуя режим эхо-контроля. При получении кода клавиши (0Dh) командный процессор предполагает, что ввод команды закончен, анализирует содержимое своего буфера и приступает к выполнению введенной команды. При этом командный процессор работает практически лишь с младшими половинами двухбайтовых кодов символов, именно, с кодами ASCII. Если компьютер выполняет какую-либо программу, ведущую диалог с оператором, то, как уже отмечалось, ввод. данных с клавиатуры (а точнее — из кольцевого буфера ввода) и вывод их на экран с целью эхо-контроля организует эта программа, обращаясь непосредственно к драйверу BIOS (INT 16h) или к соответствующей функции DOS (INT 21h). Может случиться, однако, что выполняемой программе не требуется ввод с клавиатуры, а оператор нажал какие-то клавиши. В этом случае вводимые символы накапливаются (с помощью программы INT 09h) в кольцевом буфере ввода и, естественно, не отображаются на экране. Так можно ввести до 15 символов. Когда программа завершится, управление будет передано COMMAND.COM, который сразу же обнаружит наличие символов в кольцевом буфере, извлечет их оттуда и отобразит на экране. Такой ввод с клавиатуры называют вводом с упреждением. До сих пор речь шла о символах и кодах ASCII, которым соответствуют определенные клавиши терминала и которые можно отобразить на экране. Это буквы (прописные и строчные), цифры, знаки препинания и специальные знаки, используемые в программах и командных строках, например, [, $, # и др. Однако, имеется рад клавиш, которым не назначены какие-то отображаемые на экране символы. Это, например, функциональные клавиши , . ; клавиши управления курсором , , , , и др. Очевидно, что всем этим клавишам назначены определенные скен-коды. Но как их скен-коды транслируются в коды ASCII? В таблице трансляции, с которой работает программа INT 09h, всем таким скен-кодам соответствует нулевой код ASCII. Поэтому при нажатии, например, клавиши (скен-код 3Bh) в кольцевой буфер ввода поступает двухбайтовый код ЗВ00h, а при нажатии клавиши (скен-код 47h) — двухбайтовый код 4700h. Двухбайтовые коды, содержащие на месте кода ASCII ноль, называются расширенными кодами ASCII. Эти коды (и соответствующие им клавиши) широко используются для управления программами. Например, в оболочке DOS Norton Commander нажатие функциональных клавиш вызывает выполнение определенных операций: — вывод на экран справочника, -копирование файла, — его удаление и т.д. Программы, работающие с расширенными кодами ASCII, должны, очевидно, считав из кольцевого буфера ввода младший байт и убедившись, что он равен нулю, считать далее и старший байт (в сущности скен-код) и в зависимости от его значения выполнить соответствующее действие. Системные средства ввода данных с клавиатуры DOS предоставляет три уровня процедур ввода данных с клавиатуры:
Ввод с клавиатуры средствами файловой системы (INT 21h, функция 3Fh) осуществляется точно так же, как и чтение из файла. Обычно используется предопределенный дескриптор 0, закрепленный за стандартным устройством ввода (по умолчанию за клавиатурой). Число вводимых символов указывается в регистре СХ, однако ввод завершается лишь после того, как нажата клавиша , независимо от того, введено ли фактически меньше символов, чем было запланировано, или больше (последнее, естественно, может случиться лишь при неправильных действиях).Поэтому при вводе строк с клавиатуры нет необходимости заранее задавать их длину, достаточно загрузить в регистр СХ максимальную длину строки, например, 80 байт. В любом случае в регистре АХ возвращается число реально введенных байтов, при этом учитываются также и два байта (0Ah и 0Dh), поступающие во входной буфер при нажатии клавиши . Особая ситуация возникает, если попытаться ввести больше символов, чем затребовано функцией 3Fh. В процессе выполнения этой функции все вводимые символы тут же извлекаются из кольцевого буфера ввода и пересылаются в буфер DOS. Обнаружив во входном потоке коды клавиши , DOS пересылает из этого буфера в буфер пользователя в программе точно затребованное число символов (естественно, без кодов , которые располагаются в конце вводимой строки). Остальные символы остаются в буфере DOS, готовые к вводу. Фактически, если не принять специальных мер к очистке буфера, они поступят в программу при очередном запросе 3Fh, даже если оператор еще не начал вводить очередную порцию данных. Очевидно, что в этом случае будет нарушена синхронизация хода выполнения программы с работой оператора. Второй способ получения данных с клавиатуры в программу, с помощью функций DOS для посимвольного ввода, несколько более громоздок, но обеспечивает более разнообразные возможности. Всего используется 7 функций прерывания INT 21h: 0lh — ввод символа с эхом; 06h — прямой ввод — вывод через консоль; 07h — нефильтрованный ввод без эха; 08h — ввод символа без эха; 0Ah — буферизованный ввод строки с эхом; 0Bh — проверка состояния стандартного устройства ввода; 0Сh — сброс входного буфера и ввод. ^ INT 21h, функция 0lh. Ввод символа с эхом. Вводит символ из устройства стандартного ввода и отображает его на устройстве стандартного вывода. При отсутствии символа ждет ввода. Выполняет обработку /C. Для чтения расширенного кода ASCII требуется повторное выполнение функции. При вызове: AH=01h При возврате: АL=байт входных данных ^ INT 21h, функция 06h. Прямой ввод — вывод. Вводит из устройства стандартного ввода и выводит на устройство стандартного вывода все коды символов без вмешательства DOS. Для чтения расширенного кода ASCII требуется повторное выполнение функции. При отсутствии символа не ждет его ввода, а возвращает управление в программу. При вызове: AH=06h DL=код символа (00h — FEh) (при выводе) DL=FFh (при вводе) При возврате: АL=код символа (при вводе); если символа нет, то ZF=1 ^ INT 21h, функция 07h. Нефильтрованный ввод без эха. Вводит символ из устройства стандартного ввода без его отображения. При отсутствии символа ждет ввода. Не выполняет обработку /C. Для чтения расширенного кода ASCII требуется повторное выполнение функции. При вызове: AH=07h При возврате: АL=байт входных данных ^ INT 2lh, функция 08h. Ввод символа без эха. Вводит символ из устройства стандартного ввода без его отображения. При отсутствии символа ждет ввода. Для чтения расширенного кода ASCII требуется повторное выполнение функции При вызове: AH=08h При возврате: АL=байт входных данных ^ INT 2lh, функция OAh. Буферизованный ввод с клавиатуры. Вводит строку байт из устройства стандартного ввода в буфер пользователя с отображением на устройстве стандартного вывода. Строка должна заканчиваться символом возврата каретки (0Dh). Выполняет обработку /C. При вызове: AH=0Ah При возврате: Данные помещены в буфер. Формат буфера: байт 0 — ожидаемая длина строки байт 1 — фактическая длина введенной строки байт 2 и далее — строка, заканчивающаяся 0Dh. ^ INT 2lh, функция 0Bh. Проверка состояния ввода. Проверяет наличие символа от устройства стандартного ввода. Выполняет обработку /C. При вызове: AH=0Bh При возврате: AL=00h если символ не ждет AL=FFh если символ ждет ^ INT 2lh, функция 0Ch. Очистка входного буфера и ввод. Очищает кольцевой буфер клавиатуры и активизирует функцию ввода. При вызове: AH=0Ch АL=»номер требуемой функции ввода. Допустимы функции 01, 06, 07, 08, 0Ah DS:DX=адpec буфера (если AL=0Ah) При возврате: АL=байт входных данных (если при вызове AL=0Ah, данные помещаются в буфер) Функции 0lh, 06h, 07h и 08h при каждом вызове вводят в программу один символ из кольцевого буфера ввода; при необходимости ввести группу символов (строку) функции следует использовать в цикле. Различаются эти функции наличием или отсутствием эха, а также реакцией на ввод с клавиатуры сочетания /С. Функции 0lh и 06h отображают вводимые символы на экране (эхо); функции 07h и 08h этого не делают, что дает возможность вводить данные тайком от окружающих (например, пароль или ключ). Второе важное различие описываемых функций касается их реакции на ввод сочетания /C. При выполнении функций 0lh и 08h DOS проверяет каждый введенный символ и, обнаружив во входном потоке код /C (03h),аварийно завершает программу. Функции же 06h и 07h пропускают код /C в программу, не инициируя по нему никаких специальных действий. Такой метод ввода используется прикладными программами, если перед завершением в них должны быть выполнены определенные программные действия (сброс буферов на диск, модификация файлов и проч.). Аварийное завершение такой программы средства DOS по коду /C могло бы привести к нарушению ее работоспособности. Функция 0Ah передает в буфер пользователя отроку, введенную с клавиатуры; строка должна заканчиваться нажатием клавиши . Длина строки может достигать 254 символов. Вводимые символы отображаются на экране; при вводе /C происходит аварийное завершение программы. Функция 0Bh позволяет проверить наличие в кольцевом буфере ввода ожидающих символов. При обнаружении символов программа должна извлечь их из буфера одной из функций ввода; если символов нет, программа может продолжить выполнение. Такая методика используется в программах, носящих циклический характер, если требуется обеспечить управление ходом выполнения программы с клавиатуры терминала. В каждом шаге цикла после выполнения запланированных действий проверяется состояние кольцевого буфера ввода; если в течение предыдущего шага цикла оператор нажал на какую-либо клавишу, программа проанализирует введенный код и осуществит выход из цикла и переход в ту или иную точку; если же буфер оказывается пуст, циклическое выполнение продолжится. Функция 0Bh чувствительна к /C. Это дает возможность организовать с ее помощью аварийное завершение программы на тех ее участках, где выполняются чисто процессорные действия. Если, например, включить вызов функции 0Bh в цикл, .то при отсутствии ввода с клавиатуры цикл будет выполняться обычным образом, но после ввода /C программа аварийно завершится, хотя на выполняемом участке программы не используются функции ввода-вывода. Функция 0Сh служит для организации ввода с предварительной очисткой кольцевого буфера. Все функции, кроме 0Сh, вводят в программу наиболее старый из скопившихся в кольцевом буфере ввода символов, реализуя тем самым возможность ввода с упреждением. В этом режиме оператор может нажимать на клавиши еще до выдачи программой запроса на ввод; коды нажатых клавиш (не более 15) будут накапливаться в кольцевом буфере ввода и извлекаться оттуда в программу по мере выполнения ею запросов на ввод- В отличие от этого, функция 0Сh сначала очищает кольцевой буфер и лишь затем ожидает ввода символа с клавиатуры. В результате коды всех ранее нажатых (по предположению -случайно) клавиш теряются. Обычно функция ввода 0Сh стоит в программе непосредственно вслед за функцией вывода на экран символьной строки с предложением оператору вводить данные. В результате из кольцевого буфера убирается весь «мусор» от случайных нажатий, в программу же поступает лишь то, что вводится оператором после запроса программы. При этом режим ввода (с эхом или без него и т.д.) определяется тем, какая именно функция ввода (0lh, 06h, 07h, 08h или 0Ah) реализуется «внутри»функции 0Сh. Все функции DOS ввода с клавитуры допускают перенаправление ввода (из файла, последовательного порта, из вывода другой программы). Если требуется избавиться от этого качества, следует использовать файловую функцию ввода 3Fh и специально выделенный дескриптор. Функции 0lh, 07h, 08h и 0Ah являются синхронными, т.е. при отсутствии символа в кольцевом буфере ждут его ввода. Функция 06h позволяет определить состояние кольцевого буфера и при наличии в нем кода извлечь этот код и обработать его, а при отсутствии — продолжить выполнение программы. Функции 0lh, 06h, 07h и 08h позволяют вводить в программу расширенные коды ASCII. Для этого, обнаружив, что введенный код ASCII равен нулю, следует выполнить функцию повторно. Это дает возможность управления прикладными программами с помощью функциональных клавиш, а также сочетаний /цифра, /буква Функция 06h позволяет вводить в программу коды символов с помощью сочетания / (втом числе коды первых 32 символов кодовой таблицы и вторую половину кодовой таблицы). ^ Сравнительные характеристики функций DOS ввода с клавиатуры приведены в таблице.
|