Ввод информации с клавиатуры терминала

Практическая работа №8

Для уверенной работы с машиной полезно понимать, каким образом вводятся, куда попадают и как обрабатываются символы, вводимые с клавиатуры. Процесс взаимодействия системы с клавиатурой продемонстрирован на рис.

Ввод информации с клавиатуры терминала - student2.ru

Адрес ПОП - вектора прерывания 09h (ячейки 00:24h и 00:26h)

Работой клавиатуры управляет специальная электронная схема - контроллер клавиатуры. В его функции входит распознавание нажатой клавиши и помещение закрепленного за ней кода в свой выходной регистр (порт), обычно с номером 60h. Код клавиши, поступающий в порт, называется скен-кодом и является, по существу, порядковым номером клавший, хотя последовательность скен-кодов не всегда совпадает с порядком расположения клавиш на клавиатуре. При этом каждой клавише присвоены как бы два скен-кода, отличающиеся друг от друга на 80h. Один скен-код (меньший, код нажатия) засылается контроллером в порт 60h при нажатии клавиши, другой (больший, код отпускания) - при ее отпускании.

Скен-код однозначно указывает на нажатую клавишу, однако по нему нельзя определить, работает ли пользователь на нижнем или верхнем регистре, а также вводит ли он латинские или русские буквы. С другой стороны, скен-коды присвоены всем клавишам клавиатуры, в том числе управляющим клавишам <Shift>,<Ctrl>, <Alt>, <Caps Lock> и др. Таким образом, очевидно, что определение введенного символа должно включать в себя не только считывание скен-кода нажатой клавиши, но и выяснение того, не были ли перед этим нажаты, например, клавиши <Shift> (верхний регистр) или <Caps Lock> (фиксация верхнего регистра). Всем этим анализом занимается программа обработки прерываний от клавиатуры.

Нажатие (а также и отпускание) любой клавиши вызывает сигнал аппаратного (внешнего) прерывания, заставляющий процессор прервать выполняемую программу и перейти на программу обработки прерывания (ПОП) от клавиатуры. Эта программа хранится по фиксированному адресу в постоянном запоминающем устройстве BIOS, являясь, таким образом, элементом "встроенного", или "зашитого" программного обеспечения.

Процессор вместе с сигналом прерывания получает еще и тип прерывания, или его номер. За клавиатурой закреплен номер 09h. Адрес программы обработки прерываний от клавиатуры располагается; таким образом, и векторе 09h, занимающем слова с адресами 24h и 26 h (36-38 ячейки памяти).

Получив тип прерывания и определив по нему адрес вектора, процессор извлекает из вектора адрес программы обработки прерываний и осуществляет переход на ее выполнение. Поскольку программа обработки прерываний от клавиатуры вызывается через вектор 09h, ее часто называют программой INT 09h (INT - от английского Interrupt, прерывание).

Программа INT 09h, помимо порта 60h, работает еще с двумя областями оперативной памяти: кольцевым буфером ввода, располагаемым по адресам от 40h:1Eh до 40h:3Dh, куда, в конце концов, помещаются коды ASCII нажатых клавиш, и словом состояния (словом флагов) клавиатуры, находящимся по адресу 40h:17h, где фиксируется состояние управляющих клавиш (<Shift>, <Caps Lock>, <Num Lock> и др.).

Программа INT 09h, получив управление в результате прерывания от клавиатуры, считывает из порта 60h скен-код и анализирует его значение. Если скен-код принадлежит одной из управляющих клавиш, и, к тому же, представляет собой код нажатия, в слове флагов клавиатуры устанавливается бит (флаг), соответствующий нажатой клавише. Например, при нажатии правой клавиши <Shift> в слове флагов устанавливается бит 0, при нажатии левой клавиши <Shift> - бит 1, при нажатии любой клавиши <Ctrl> -бит 2, а при нажатии <Alt> (тоже любой) - бит 3. Биты флагов сохраняют свое состояние пока клавиши (по одиночке или в любых комбинациях) остаются нажатыми. Если управляющая клавиша отпускается, программа INT 09h получает скен-код отпускания и сбрасывает соответствующий бит в слове флагов.

Кроме состояния указанных клавиш, в слове флагов фиксируются еще режимы <Scroll Lock>, <Num Lock>, <Caps Lock> и <Insert>, а в 101-клавишной клавиатуре на компьютерах РС/АТ также состояния клавиш <SysRq>, <Ctrl>-левая, <Аlt>-левая и режим паузы (<Ctrl> /<Num Lock>).

При нажатии любой другой клавиши программа INT 09h считывает из порта 60h ее скен-код нажатия и по таблице трансляции скен-кодов в коды ASCII формирует двухбайтовый код, старший байт которого содержит скен-код, а младший - код ASCII. При этом если скен-код характеризует клавишу, то код ASCII определяет закрепленный за ней символ. Поскольку за каждой клавишей закреплено, как правило, не менее двух символов ("а"и "А", "1" и "!", "2" и"@" и т.д.), то каждому скен-коду соответствуют, как минимум, два кода ASCII. В процессе трансляции программа INT 09h анализирует состояние флагов, так что если нажата, например, клавиша Q (скен-код 10h, код ASCII буквы Q - 51 h, а буквы q - 71h), то формируется двухбайтовый код 1071h, но если клавиша Q нажата при нажатой клавише <Shift> (смена регистра), то результат трансляции составит 105lh. Тот же код 105lh получится, если при нажатии клавиши Q был включен режим <Caps Lock> (заглавные буквы), однако при включенном режиме <Caps Lock> и нажатой клавише <Shift> образуется код 107lh, поскольку в такой ситуации клавиша <Shift> на время нажатия переводит клавиатуру в режим нижнего регистра (строчные буквы).

Полученный в результате трансляции двухбайтовый код засылается программой INT 09h в кольцевой буфер ввода, который служит для синхронизации процессов ввода данных с клавиатуры и приема их выполняемой компьютером программой. Объем кольцевого буфера составляет 15 слов, при этом дисциплина его обслуживания такова, что коды символов извлекаются из него в том же порядке, в каком они в него поступали. За состоянием буфера следят два указателя. В хвостовом указателе (слово по адресу 40:lCh) хранится адрес первой свободной ячейки, в головном указателе (40: lAh) - адрес самого старого кода, принятого с клавиатуры и еще не востребованного программой. В начале работы, когда буфер пуст, оба указателя - и хвостовой, и головной, указывают на первую ячейку буфера.

Программа INT 09h, сформировав двухбайтовый код, помещает его в буфер по адресу, находящемуся в хвостовом указателе. после этого этот адрес увеличивается на 2, указывая опять на первую свободную ячейку. Каждое последующее нажатие на какую-либо клавишу добавляет в буфер очередной двухбайтовый код и смещает хвостовой указатель.

Выполняемая программа, желая получить код нажатой клавиши, должна вызвать прерывание INT 16h, которое активизирует драйвер клавиатуры - BIOS. Драйвер считывает из кольцевого буфера содержимое ячейки, адрес которой находится в головном указателе, и увеличивает этот адрес на 2. Таким образом, программный запрос на ввод с клавиатуры фактически выполняет прием кода не с клавиатуры, а из кольцевого буфера.

Хвостовой указатель, перемещаясь по буферу в процессе занесения в него кодов, доходит, наконец, до конца буфера (адрес40h:ЗСh). В этом случае при поступлении очередного кода адрес в указателе не увеличивается, а, наоборот, уменьшается на длину буфера. Тем самым указатель возвращается в начало буфера, после чего продолжает перемещаться по буферу до его конца, опять возвращается в начало и так далее по кольцу. Аналогичные манипуляции выполняются и с головным указателем.

Равенство адресов в обоих указателях свидетельствует о том. что буфер пуст. Если при этом программа вызвала прерывание INT 16h, то драйвер клавиатуры будет ждать поступления кода в буфер, после чего он будет передан в программу. Если же хвостовой указатель, перемещаясь по буферу в процессе его заполнения, подошел к головному указателю "с обратной стороны" (это произойдет, если оператор нажимает на клавиши, а программа не выполняет запросы к драйверу клавиатуры), прием новых кодов блокируется, а нажатие на клавиши возбуждает предупреждающие звуковые сигналы. Если компьютер находится в пассивном состоянии ожидания команд DOS с клавиатуры, то за состоянием кольцевого буфера ввода следит командный процессор COMMAND.COM. Как только в буфере появляется код символа, командный процессор с помощью соответствующих системных программ переносит его в свой внутренний буфер командной строки, очищая при этом кольцевой буфер ввода, а также выводит символ на экран, организуя режим эхо-контроля. При получении кода клавиши <Enter> (0Dh) командный процессор предполагает, что ввод команды закончен, анализирует содержимое своего буфера и приступает к выполнению введенной команды. При этом командный процессор работает практически лишь с младшими половинами двухбайтовых кодов символов, именно, с кодами ASCII.

Если компьютер выполняет какую-либо программу, ведущую диалог с оператором, то, как уже отмечалось, ввод. данных с клавиатуры (а точнее - из кольцевого буфера ввода) и вывод их на экран с целью эхо-контроля организует эта программа, обращаясь непосредственно к драйверу BIOS (INT 16h) или к соответствующей функции DOS (INT 21h). Может случиться, однако, что выполняемой программе не требуется ввод с клавиатуры, а оператор нажал какие-то клавиши. В этом случае вводимые символы накапливаются (с помощью программы INT 09h) в кольцевом буфере ввода и, естественно, не отображаются на экране. Так можно ввести до 15 символов. Когда программа завершится, управление будет передано COMMAND.COM, который сразу же обнаружит наличие символов в кольцевом буфере, извлечет их оттуда и отобразит на экране. Такой ввод с клавиатуры называют вводом с упреждением.

До сих пор речь шла о символах и кодах ASCII, которым соответствуют определенные клавиши терминала и которые можно отобразить на экране. Это буквы (прописные и строчные), цифры, знаки препинания и специальные знаки, используемые в программах и командных строках, например, [, $, # и др. Однако, имеется рад клавиш, которым не назначены какие-то отображаемые на экране символы. Это, например, функциональные клавиши <F1>, <F2>...<F10>; клавиши управления курсором <Ноmе>, <End>, <PgUp>, <PgDn>, <Стрелка вправо>, <Стрелка вниз> и др. Очевидно, что всем этим клавишам назначены определенные скен-коды. Но как их скен-коды транслируются в коды ASCII?

В таблице трансляции, с которой работает программа INT 09h, всем таким скен-кодам соответствует нулевой код ASCII. Поэтому при нажатии, например, клавиши <F1> (скен-код 3Bh) в кольцевой буфер ввода поступает двухбайтовый код ЗВ00h, а при нажатии клавиши <Ноmе> (скен-код 47h) - двухбайтовый код 4700h. Двухбайтовые коды, содержащие на месте кода ASCII ноль, называются расширенными кодами ASCII. Эти коды (и соответствующие им клавиши) широко используются для управления программами. Например, в оболочке DOS Norton Commander нажатие функциональных клавиш вызывает выполнение определенных операций: <F1> - вывод на экран справочника, <F5> -копирование файла, <F8> - его удаление и т.д.

Программы, работающие с расширенными кодами ASCII, должны, очевидно, считав из кольцевого буфера ввода младший байт и убедившись, что он равен нулю, считать далее и старший байт (в сущности скен-код) и в зависимости от его значения выполнить соответствующее действие.

Широкое использование в компьютерах интерактивных средств потребовало расширения возможностей ввода с клавиатуры управляющей информации, которую программа должна легко отличать от вводимого текста. С этой целью в компьютерах типа IBM PC расширенные коды ASCII генерируются не только функциональными клавишами и клавишами управления курсором, но и всеми алфавитно-цифровыми клавишами, если они нажимаются вместе с клавишей <Alt>. Таким образом, если нажатие клавиши Q посылает в кольцевой буфер двухбайтовый код1071h (или 105lh на верхнем регистре), то нажатие сочетания <Alt>/Q генерирует расширенный код ASCII l000h, где 10 - скен-код клавиши, а 00- признак расширенного кода ASCII. Расширенные коды ASCII генерируются также при нажатии клавиш <Alt>, <Ctrl> или <Shift> одновременно с функциональными клавишами<F1>.,<F10>. В этом случае, однако, в старший байт расширенного кода ASCII помещается уже не скен-код клавиши, а некоторый код, специально назначенный этой комбинации клавиш. Естественно, этого кода нет среди "обычных" скен-кодов. Например, клавиша <F1>, скен-код которой равен 3Bh, может генерировать следующие расширенные коды ASCII:

<F1> -3B00h <Shift>/<Fl> - 5400h:

<Ctrl>/<Fl> - 5E00h <Alt>/<Fl> - 6800h

Системные средства ввода данных с клавиатуры

DOS предоставляет три уровня процедур ввода данных с клавиатуры:

· обращение к клавиатуре, как к файлу, с помощью прерывания DOS INT 21h с функцией 3Fh;

· использование группы функций DOS INT 21h, обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

· посимвольный или, лучше сказать, покодовый ввод путем обращения в обход DOS непосредственно к драйверу BIOS с помощью прерывания INT 16h.

Ввод с клавиатуры средствами файловой системы (INT 21h, функция 3Fh) осуществляется точно так же, как и чтение из файла. Обычно используется предопределенный дескриптор 0, закрепленный за стандартным устройством ввода (по умолчанию за клавиатурой). Число вводимых символов указывается в регистре СХ, однако ввод завершается лишь после того, как нажата клавиша <Enter>, независимо от того, введено ли фактически меньше символов, чем было запланировано, или больше (последнее, естественно, может случиться лишь при неправильных действиях).Поэтому при вводе строк с клавиатуры нет необходимости заранее задавать их длину, достаточно загрузить в регистр СХ максимальную длину строки, например, 80 байт. В любом случае в регистре АХ возвращается число реально введенных байтов, при этом учитываются также и два байта (0Ah и 0Dh), поступающие во входной буфер при нажатии клавиши <Enter>.

Особая ситуация возникает, если попытаться ввести больше символов, чем затребовано функцией 3Fh. В процессе выполнения этой функции все вводимые символы тут же извлекаются из кольцевого буфера ввода и пересылаются в буфер DOS. Обнаружив во входном потоке коды клавиши <Enter>, DOS пересылает из этого буфера в буфер пользователя в программе точно затребованное число символов (естественно, без кодов <Enter>, которые располагаются в конце вводимой строки). Остальные символы остаются в буфере DOS, готовые к вводу. Фактически, если не принять специальных мер к очистке буфера, они поступят в программу при очередном запросе 3Fh, даже если оператор еще не начал вводить очередную порцию данных. Очевидно, что в этом случае будет нарушена синхронизация хода выполнения программы с работой оператора.

Второй способ получения данных с клавиатуры в программу, с помощью функций DOS для посимвольного ввода, несколько более громоздок, но обеспечивает более разнообразные возможности. Всего используется 7 функций прерывания INT 21h:

0lh - ввод символа с эхом;

06h - прямой ввод - вывод через консоль;

07h - нефильтрованный ввод без эха;

08h - ввод символа без эха;

0Ah - буферизованный ввод строки с эхом;

0Bh - проверка состояния стандартного устройства ввода;

0Сh - сброс входного буфера и ввод.

Описание функций:

Наши рекомендации