Dos fn 01h ввод с клавиатуры


Содержание

Dos fn 01h: ввод с клавиатуры

Способы ввода данных с клавиатуры

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

Ввод с клавиатуры.

Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). Ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. Первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.

Нефильтрующий консольный ввод без эха.

Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не фильтрует: Не проверяет на Ctrl-Break, backspace и т.п. Необходимо вызывать дважды для ввода расширенного символа ASCII.

Консольный ввод без эха.

Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23H. Необходимо вызывать дважды для ввода расширенного символа ASCII.

Буферизированный ввод строки.

DS:DX=адрес входного буфера (смотри ниже)

Выход: буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)

Описание: При входе буфер по адресу DS:DX должен быть оформлен следующим образом:

MAX — максимально допустимая длина ввода (от 1 до 254) При выходе буфер заполнен данными следующим образом:

max len T E X T … 0dh

LEN — действительная длина данных без завершающего CR (здесь – 0dH). Символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. Если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter). Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. Последний символ в буфере -всегда CR (который не засчитан в байте длины). Символы в буфере (включая LEN) в момент вызова используются как «шаблон». В процессе ввода действительны обычные клавиши редактирования: Esc выдает «\» и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает «@» и сохраняет текущую строку как шаблон, и т.д. Большинство расширенных кодов ASCII игнорируются. При распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).

Ввод с очисткой

AL= номер функции ввода DOS (01H, 06H, 07H, 08H или 0aH)

Описание: Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. Это заставляет систему ожидать ввод очередного символа. Следующие значения допустимы в AL: 01H Ввод с клавиатуры; 06H Ввод с консоли; 07H Нефильтрующий без эха; 08H Ввод без эха; 0aH Буферизованный ввод.

Далее программы будут оформляться в виде COM.

Рассмотрим программу которая осуществляет ввод строки с клавиатуры и заменяет все буквы «а» на заглавные, причем пробелы удаляются.

Функция 0ah: Ввод строки с клавиатуры в буфер

DS:DX = адрес входного буфера (смотри ниже)

Выход Буфер содержит ввод, заканчивающийся символом CR (ASCII 0dh)

Описание: При обращении буфер по адресу DS:DX должен содержать значение максимально допустимой длины ввода. На выходе функции в следующем байте содержится действительная длина ввода, затем введенный текст, завершающийся символом возврата каретки (0dh). Символы считываются с устройства стандартного ввода вплоть до CR (ASCII 0dh) или до достижения длины MAX-1. Если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter). Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. Последний символ в буфере — всегда CR (не засчитан в байте длины). Символы в буфере (включая LEN) в момент вызова используются как «шаблон». В процессе ввода действительны обычные клавиши редактирования: Esc выдает «\» и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает «@» и сохраняет текущую строку как шаблон, и т. д. Большинство расширенных кодов ASCII игнорируются. При распознавании Ctrl-Break выполняется прерывание int 23h (буфер остается неизменным).

Завершение программы

Функция 4ch: Завершить программу (EXIT)

Вход AH = 4ch

AL = код возврата

Описание: Возвращает управление от порожденного процесса его родителю, устанавливая код возврата, который можно опросить функцией 4dh WAIT. Управление передается по адресу завершения в PSP завершаемой программы. В векторах Ctrl-Break и Critical Error восстанавливаются старые значения, сохраненные в родительском PSP.

Замечание: Значение ERRORLEVEL (используемое в пакетных файлах DOS) можно использовать для проверки кода возврата самой последней программы.

Функция 4dh: Дать код возврата программы (WAIT)

Вход AH = 4dh

Выход AL = код возврата последнего завершившегося процесса

AH = 0 — нормальное завершение

АН = 1 — завершение через Ctrl-Break int 23h

АН = 2 — завершение по критической ошибке устройства int 24h

АН = 3 — завершение через функцию 31h KEEP

Описание: Возвращает код возврата последнего из завершившихся процессов. Эта функция возвращает правильную информацию только однажды для каждого завершившегося процесса.

Функция 4dh: Дать код возврата программы (WAIT)

Вход AH = 4dh

Выход AL = код возврата последнего завершившегося процесса

AH = 0 — нормальное завершение

АН = 1 — завершение через Ctrl-Break int 23h

АН = 2 — завершение по критической ошибке устройства int 24h

АН = 3 — завершение через функцию 31h KEEP

Описание: Возвращает код возврата последнего из завершившихся процессов. Эта функция возвращает правильную информацию только однажды для каждого завершившегося процесса.

Работа с файлами

Функция 3ch: Создать файл через дескриптор

Вход AH = 3ch

DS:DX = адрес строки ASCIIZ с именем файла

CX = атрибут файла

Выход AX = код ошибки, если CF установлен

АХ = дескриптор файла, если ошибки нет

Описание: DS:DX указывает на строку ASCIIZ в формате: «d:\путь\имяфайла»,0. Если диск и/или путь опущены, они принимаются по умолчанию. файл создается в указанном (или текущем) каталоге файл открывается в режиме доступа чтение/запись вы должны сохранить дескриптор (handle) для последующих операций, если файл уже существует:

· при открытии файл усекается до нулевой длины

· если атрибут файла — только чтение, открытие отвергается (атрибут можно изменить функцией 43h Изменить Атрибут)

CONFIG.SYS определяет число доступных дескрипторов в системе

Используйте функцию 5bh Создать Новый Файл, если вы не хотите

испортить существующий файл.

Функция 5bh: Создать новый файл

Вход AH = 5bh DOS 3.0+

DS:DX = адрес строки ASCIIZ с именем файла

CX = атрибут файла

Выход AX = код ошибки, если CF установлен

АХ = дескриптор файла, если ошибок нет

Описание: DS:DX указывает на строку ASCIIZ в форме: «d:\путь\имя_файла»,0. Если диск и/или путь опущены, они принимаются по умолчанию. Этот вызов идентичен функции DOS 3ch CREATE, с тем исключением, что он вернет ошибку, если файл с заданным именем уже существует. Файл открывается для чтения/записи в совместимом Режиме Доступа.

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.

Папиллярные узоры пальцев рук — маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни.

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰).

«Assembler IBM PC 7. Лабораторная работа № 2. Системные функции dos ввода-вывода информации. Обработка строковых переменных»

7.1. ЦЕЛЕВЫЕ УСТАНОВКИ

· Освоение стандартных способов ввода-вывода DOS.

· Разработка программ по обработке символьной информации с использованием строковых команд.

7.2. МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ

7.2.1. ВЫЗОВЫ ФУНКЦИЙ MS-DOS ДЛЯ ВВОДА-ВЫВОДА СИМВОЛЬНОЙ ИНФОРМАЦИИ

Для того чтобы написать простую, но законченную программу, необходимо знать три вещи – как вводить данные, как выводить результат и как остановить выполнение программы. В языках высокого уровня имеются специальные операторы ввода/вывода, которые позволяют в удобной форме реализовать эти функции. В системе команд процессора ix86 также имеются команды ввода/вывода, но они реализуют эти операции на самом низком, физическом уровне, т.е. обеспечивают обращение к портам ввода/вывода по конкретным адресам. Для обеспечения ввода/вывода информации на этом уровне программист должен знать номера портов каждого устройства, а также протоколы или алгоритмы обслуживания этих устройств. Операционная система MS DOS реализует ряд сервисных функций ввода/вывода на логическом уровне, которые выступают как пронумерованные функции прерывания Int 21h. При этом прикладная программа пользователя должна сообщить необходимые для данной функции параметры и передать управление DOS, которая и осуществит все необходимые операции по управлению устройством на физическом уровне (где-то, возможно, обратится за помощью к BIOS), а затем вернёт управление прикладной задаче, сообщив, успешно ли завершилась операция или же была допущена ошибка.

Прерывания, в основном, можно разделить на два основных типа: аппаратные (hardware) и программные (software interrupt). Аппаратные прерывания вызываются сигналами от периферийных устройств, требующими обслуживания процессором, а программные, через посредство команды Int, вызывающей какую-либо сервисую функцию (процедуру) DOS или BIOS. Перечень функций, выполняемых операционной системой DOS, подробно изложен в п. 3.

Упрощенная схема обработки прерывания изображена на рис. 2.1. Процессор выполняет команду прерывания, используя таблицу векторов, где содержатся все адресные указатели обработчиков (аппаратных и программных) прерываний. Действия процессора при переходе на выполнение подпрограммы-обработчика (инициируемое командой Int n) и последующем возврате обратно (при встрече команды Iret) в точку выхода из основной программы показаны на рис. 2.1 цифрами в кружках. Одно и то же прерывание может выполнять несколько различных функций, код которых помещается в регистрah, а дополнительные параметры заносятся в другие регистры РОН. Возвращаемая обработчиком информация содержится в регистре al или ax, если флаг cf=0. Флаг cf устанавливается в 1, если произошла какая-либо ошибка, код которой заносится в регистр ax (так называемый код возврата ошибки). Возможные коды ошибок приводятся в руководствах по DOS [4, 10, 12].

Рис. 2.1. Упрощенная схема обработки программного прерывания Int n

Функции информационного обмена MS DOS в своём развитии изменялись от специализированных программ обмена для каждого типа устройства на основе блока управления файлами FCB (File ControlBlock) до унификации обмена на основе файловой системы через дескрипторы. Дескриптор или логический номер файла идентифицирует файл или устройство, с которым должна работать прикладная программа. Это упрощает программирование операций ввода/вывода, т.к. позволяет осуществлять обмен информации независимо от природы файла (устройства). Существует пять стандартных дескрипторов файлов, которые предоставляются прикладной программе:

· – стандартный ввод с консоли (обычно клавиатура);

· 1 – стандартный вывод на консоль (обычно экран дисплея);


· 2 – устройство вывода ошибок (всегда дисплей);

· 3 – внешнее устройство обмена AUX (асинхронный адаптер COM1);

· 4 – стандартный принтер (первый параллельный порт LPT1).

Стандартный ввод (как и стандартный вывод) можно перенаправить средствами DOS на любое устройство или в файл, а стандартная ошибка всегда связана с экраном (обычно дескриптор 2 используют для вывода диагностических сообщений). Перенаправление ввода или вывода программы осуществляет командный процессор Command.com. Если, допустим, в программе prog предусмотрен ввод данных через дескриптор стандартного ввода ²0², а вывод данных через дескриптор вывода ²1², то при обычном запуске программы командой prog.exe программа будет требовать входные данные с клавиатуры и выводить результаты своей работы на экран. Если, однако, при запуске программы использовать символ перенаправления

то система сама создаст файл file.txt, и весь вывод программы будет записан в этот файл. Ввод по-прежнему будет осуществляться с клавиатуры. Запуск программы командой

заставит программу выполняться в режиме ввода информации из файла file.dat и вывода в файл file.txt. Ни экран, ни клавиатура использоваться не будут. Сама программа ничего не знает об этих перенаправлениях – она во всех случаях обращается к стандартному устройству ввода данных и к стандартному устройству вывода данных. Просто DOS как бы подставляет ей на входе и выходе другие устройства.

7.2.2. ВВОД С КЛАВИАТУРЫ СИМВОЛЬНОЙ ИНФОРМАЦИИ

7.2.2.1. Буфер ввода данных с клавиатуры

Нажатие любой клавиши клавиатуры вызывает сигнал аппаратного прерывания (прерывания с типом 09h), заставляющий процессор прервать исполняемую программу и перейти на подпрограмму обработки прерывания от клавиатуры. Обработчик прерывания формирует двухбайтовый код с последующей засылкой его в кольцевой буфер ввода данных с клавиатуры, располагающийся по адресу 0040h:001Eh в системной области оперативной памяти. Для алфавитно-цифровых клавиш старший байт этого кода представляет scan-код клавиши (условный номер клавиши на клавиатуре), а младший – ASCII-код клавиши, т.е. 8-битовый код закреплённого за этой клавишей символа.

Заполнение буфера клавиатуры, рассчитанного на 15 слов или ударов по клавишам, происходит по мере нажатия клавиш и не связано с выполнением текущей программы. Если программе требуется ввести с клавиатуры определённый символ (или строку), она с помощью соответствующей системной функции DOS обращается к буферу ввода и, при наличии в нём данных, передаёт первый из поступивших в этот буфер символов в программу. Дело в том, что запись и считывание кодовых слов в буфер клавиатуры соответствует принципу FIFO (first in – first out, первым вошёл – первым вышел), поэтому считывание символа из буфера освобождает место для ввода последующих. Если к моменту вызова функции DOS буфер ввода оказывается пуст, DOS будет непрерывно опрашивать его состояние, ожидая появления в буфере очередного кода, а исполнение программы приостанавливается до нажатия клавиши.

7.2.2.2. Системные функции DOS ввода данных с клавиатуры

DOS предоставляет несколько способов ввода данных с клавиатуры [4, 5, 7, 11, 12, 13, 14]:

¨ использование группы функций Int 21h (01h, 06h, 07h, 08h, 0Ah¸0Ch), обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

¨ обращение к клавиатуре, как к файлу, с помощью функции 3Fh.

Функции DOS, осуществляющие ввод с клавиатуры, различаются друг от друга некоторыми другими важными характеристиками, которые приведены в табл. 2.1.

Сравнительная характеристика функций DOS ввода с клавиатуры

Номер функции DOS

01h

06h

07h

08h

0Ah

0Bh

Ch

Реакция на Ctrl+C

Ожидание нажатия клавиши

Ввод расширенных кодов ASCII

Ввод кодов с помощью Alt/цифра

Эхо-символы. Отображение вводимого символа на экране.

Реакция на Ctrl+C. Аварийное завершение программы (ASCII-код 03h). Вызывается обработчик прерывания Int 23h, завершающий текущую программу с выходом в DOS.

Ожидание нажатия клавиши. Функция, при отсутствии символа в кольцевом буфере ожидает его ввода. Функции, обладающие этим свойством, являются синхронными, иначе – асинхронными.

Ввод расширенных кодов ASCII. Все функции DOS, считывающие данные с клавиатуры, передают в программу только ASCII-код (младший байт кодового слова клавиши), оставляя scan-код (старший байт) без внимания. Правда, это относится только к алфавитно-цифровым клавишам, т. е. клавишам, за которыми закреплены отображаемые на экране символы (94 символа со значениями ASCII-кода от 32 до 126). Особенности считывания информационных кодов с других, так называемых функциональных и управляющих клавиш, будут рассмотрены дальше в разделе ²Расширенные коды ASCII².

Очистка буфера. Процесс считывания кодов с буфера ввода может дать непредсказуемый эффект, если перед вызовом функции DOS этот буфер не был пуст. Программа, не желающая вводить набранные досрочно коды, должна очистить клавиатурный буфер с помощью специальной функции Ch прерывания 21h (при al = 0).

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

¨ Функция 01h. Ввод одиночного символа с эхом.

Вводит символ из стандартного устройства ввода и отображает его на устройстве стандартного вывода. Ввод каждого символа сопровождается перемещением курсора вправо на следующую позицию. При отсутствии символа ждёт ввода. При наборе строки обрабатываются управляющие клавиши: BS (шаг назад без удаления символа, AL = 08h), TAB (табуляция, AL = 09h), ENTER (переход на начало текущей строки, AL = 13h). Допустимо перенаправление ввода. Если ввод не перенаправлен, выполняет обработку . Для чтения расширенного кода ASCII требует повторного выполнения функции.

¨ Функция 06h. Ввод одиночных символов из стандартного устройства ввода и вывод одиночных символов на стандартное устройство вывода.

Режим работы определяется содержанием регистра DL в момент вызова функции: DL = FF – режим ввода, DL = <FFh – 00h > – режим вывода соответствующего этому коду символа. В режиме вывода коды ASCII: 07h – звонок, Dh – возврат каретки, Ah – перевод строки, рассматриваются как управляющие и выполняются соответствующие им действия.

Если вводимый символ в устройстве ввода присутствует, то он помещается в AL (без эха) с установкой флага ZF = 0, иначе ZF = 1. Отличительным качеством функции 06h является то обстоятельство, что она, просматривая устройство ввода, не останавливает программы (является асинхронной), если не обнаруживает в нём символа, а просто устанавливает флаг ZF = 1. Допускает перенаправление ввода-вывода. Для чтения расширенного кода ASCII требуется повторное выполнение функции.

Вызов: AH =06h, Int 21h.

ZF = 1 – устройство ввода пустое.

Вывод: DL = FE¸00. Код в регистре DL является одновременно и кодом выводимого символа.

¨ Функция 07h. Нефильтрованный ввод символа без эха.

Вводит символ из стандартного устройства ввода без его отображения на экране. При отсутствии символа ждёт его ввода. Допустимо перенаправление ввода. Не выполняет отработку . Для чтения расширенного кода ASCII требует повторное выполнение функции. Функция, как правило, используется для ввода пароля с целью защиты программы от несанкционированного запуска

¨ Функция 08h. Ввод символа без эха.

Вводит символ из стандартного устройства ввода. При отсутствии символа ждёт его ввода. Допустимо перенаправление ввода. Для чтения расширенного кода ASCII требует повторное выполнение функции. Если ввод не перенаправлен, чувствительна к (иначе надо предварительно включить режим Break). Как и функция 07h, используется для ввода пароля. Пример использования данной функции будет рассмотрен в одной из программ этой работы.

Вызов: AH = 08h, Int 21h.

Вывод: AL = код символа.

¨ Функция Ah. Буферизованный ввод с клавиатуры.

Вводит строку байт из устройства стандартного ввода в буфер пользователя по адресу DS:DX, с отображением на устройстве стандартного вывода. Допустимо перенаправление ввода. Если ввод не перенаправлен, выполняет отработку (иначе надо предварительно включить режим Break). Функция допускает редактирование данных при их вводе клавишами: Backspace (отмена последнего символа), Exc (отмена всего набранного текста), F5 (запоминает текущую строку как подсказку), F3 (восстанавливает подсказку для ввода). Ввод символов строки заканчивается нажатием клавиши , код которой (0Dh) вводится в качестве последнего символа в отведённый буфер.

Структура буфера (резервируется в сегменте данных): байт 0 – назначаемая пользователем максимальная длина строки (1-254) с учётом символа CR (код Dh), байт 1 – число реально введённых символов без учёта символа CR, байт 2 и далее – строка. В следующем примере приведена процедура In_string ввода строки в буфер, емкостью 50 символов. Она возвращает адрес первого символа строки в регистре DX, а число символов в регистре CX.

Buf DB 50. 50 DUP(?) ;Буфер пользователя

lea dx,[Buf] ;Адрес буфера пользователя

mov ah,0Ah ;Запрос функции 0Ah

int 21h ;Вызов DOS

mov cl,[Buf+1] ;Поместить счётчик символов в cx

add dx,2 ;Сделать dx указателем строки

¨ Функция 0Bh. Проверка состояния ввода.

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

Возврат: Если символа нет, то AL = 0, если символ ждет, то AL = FFH.

¨ Функция 0Ch. Вызов служебной функции DOS для ввода данных с предварительной очисткой буфера клавиатуры. Допускает переопределение ввода.

Вызов: AH = 0Ch, Int 21h,

AL = номер функции ввода: 01, 07, 08, 0Ah (если AL = 0, то только очистка), DS:DX = адрес буфера, если AL = 0Ah.

Выход: AL = байт входных данных (если при вызове Al = 0Ah, данные помещаются в буфер).

¨ Функция 3Fh. Ввод данных из файла или устройства.

Универсальная функция ввода данных в буфер с указателем DS:DX из источника, определённого дескриптором в регистре BX. Допускает переопределение ввода. В регистре CX указывается число байтов, которое необходимо ввести. Пример использования.

In_Area DB 20 DUP(?)

mov ah,3Fh ;Запрос функции 3Fh

mov bx,00h ;Дескриптор ввода (клавиатуры)

mov cx,20 ;Число пересылаемых байт

lea dx,[In_Area] ;Адрес буфера ввода

int 21h ;Вызов функции DOS

sub cx,2 ;Фактически введено

Команда Int 21h ожидает окончания ввода символов, которое фиксируется нажатием клавиши Enter. После ввода текста и нажатия клавиши Enter в буфер In_Aria автоматически вводятся два управляющих символа: CR (код 0Dh) и LF (код 0Ah). Вследствие данной особенности максимальное число символов и размер буфера ввода должны содержать место для двух дополнительных символов. При успешном завершении операции флаг CF = 0, а в регистре AX устанавливается число байтов, введённых с клавиатуры (плюс два дополнительных символа). Если CF = 1, то в регистре AX содержится возвратный код ошибки. Это либо 5 (отказ в доступе), либо 6 (неверный дескриптор).

К особенностям использования данной функции следует отнести автоматический переход на новую строку по окончании ввода данных.

7.2.3. ФУНКЦИИ DOS ВЫВОДА ДАННЫХ НА ЭКРАН

DOS предоставляет следующие способы вывода данных на экран:

использование функций Int 21h (02h, 06h, 09h), обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

обращение к экрану, как к файлу, с помощью функции 40h.

¨ Функция 02h. Вывод одиночного символа.

Выводит символ, находящийся в регистре DL, на экран, после чего курсор сдвигается на одну позицию вправо. Для вывода строки функцию следует использовать в цикле. Допустимо перенаправление вывода. Выполняет обработку при вводе этой комбинации с клавиатуры перед выводом каждого 64-го символа. Эта функция выводит и управляющие ASCII-символы с кодами 07h, 08h, 09h, 0Ah, 0Dh. Символ с кодом 07h (bell, звонок) вызывает звуковой сигнал, с кодом 08h (backspace, забой) – возвращает курсор на одну позицию влево, с кодом 09h (tab, табуляция) – смещает курсор на одну позицию вправо, кратную 8. Действия управляющих клавиш с кодами Ah и Dh рассматривались ранее.

Вызов: AH = 02h, Int 21h.

Выход: DL = ASCII – код символа,

AL = код последнего записанного символа (кроме случая, когда DL = 09, тогда возвращается значение 20h).

Использование данной функции рассмотрим на примере процедуры перехода на новую строку.

mov ah,2 ;Запрос функции 02h


mov dl,13 ;Возврат каретки

int 21h ;Вызов DOS

mov dl,10 ;перевод строки

int 21h ;Второй вызов DOS

¨ Функция 09h. Вывод строки.

Выводит строку символов на устройство стандартного вывода (используется в системных программах для вывода на экран информационных сообщений). Строка должна заканчиваться символом $ (код24h), который служит признаком конца строки, и сам не выводится. Допустимо перенаправление вывода. В сообщение могут быть включены и управляющие коды (07h, 08h, 09h, 0Ah, 0Dh), которые вызывают соответствующие им действия (см. функцию 02h). Допустимо использование Exc-последовательностей. Функция выполняет обработку при вводе этой комбинации с клавиатуры перед выводом каждого 64-го символа.

lea dx,[Promt] ;Адрес строки Promt: DS:DX

mov ah,09h ;Запрос функции 09h

int 21h ;Вызов DOS

¨ Функция 40h. Вывод данных в файл или в устройство.

Универсальная функция вывода данных из буфера пользователя в сегменте данных в файл или на устройство, дескриптор которого указывается в регистре BX. Дескриптор 1, закреплённый за стандартным устройством вывода, обеспечивает перенаправление вывода. Значение регистра CX определяет число байтов, которые должны быть выведены, а пара регистров DS:DX указывает адрес выводимых данных. Управляющие коды 08h, 0Ah, 0Dh и некоторые другие приводят к выполнению соответствующих им действий. После завершения вывода при CF = 0 регистр AX содержит число действительно выведенных байтов, а при CF =1 – возвратный код ошибки. Как и при использовании функции 3Fh, это коды ошибок 5 или 6. Пример использования.

Out_Area DB 20 DUP(?)

mov ah,40h ;Запрос функции 40h

mov bx,01 ;Дескриптор дисплея

mov cx,20 ;Число пересылаемых байт

lea dx,[Out_Area] ;Адрес буфера для выводимого сообщения

int 21h ;Вызов DOS

7.2.4. РАСШИРЕННЫЕ КОДЫ ASCII И УПРАВЛЕНИЕ ПРОГРАММОЙ С КЛАВИАТУРЫ

Как уже отмечалось в п 7.2.2, рассмотренный процесс считывания ASCII-кодов клавиш клавиатуры с помощью системных функций DOS относится к алфавитно-цифровым клавишам, за которыми закреплены ASCII-таблицей отображаемые символы (буквы, цифры, знаки препинания и др.). Кроме них, на клавиатуре персонального компьютера имеется ряд клавиш, которым не назначены какие-либо отображаемые символы. Это, например, функциональные клавиши . , клавиши управления курсором , , . , , , специальные клавиши , , а также использующие на практике различные сочетания клавиш с , и . В этом случае, в качестве scan-кода клавиши или какой-либо комбинации из них выступает также старший байт кодового слова, но уже при нулевом младшем байте (нулевом коде ASCII). Например, при нажатии клавиши в кольцевой буфер ввода клавиатуры поступает код 3B00h, а клавиши – 4700h.

Двухбайтовые коды клавиш, содержащие на месте кода ASCII – ноль, называются расширенными кодами ASCII. Эти коды (и соответствующие им клавиши) широко используются для управления программами. Для доказательства этого утверждения достаточно указать на популярную оболочку DOS – Norton Commander. Широкое использование в компьютерах интерактивных средств требовало расширение возможностей ввода с клавиатуры управляющей информации, которую программа должна отличать от вводимого текста. Поэтому расширенные коды ASCII генерируются и всеми алфавитно-цифровыми клавишами, если они нажимаются совместно с клавишей . В табл. 2.2 приведены значения расширенных ASCII-кодов для одиночных клавиш.

Расширенные коды для функциональных клавиш

Клавиша

Код (hex)

Клавиша

Код (hex)

Клавиша

Код (hex)

Клавиша

Код (hex)

Правая часть клавиатуры.

«Num Lock-выкл»

В составе комбинации Alt+

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

Обратим здесь внимание на важный момент! Расширенный код ASCII можно считать, если программа будет настроена на проверку нулевого значения младшего байта для каждого нажатия клавиши. Пример использования функциональных клавиш для управления программой показан в листинге 2.1.

Листинг 2.1. Фрагмент программы, демонстрирующий выполнение альтернативных действий на основе анализа расширенных кодов ASCII

mes1 DB 13,10,’Сообщение $’

mes2 DB 13,10,’Сообщение $’

mes3 DB 13,10,’Сообщение $’

Илон Маск рекомендует:  Ввод номера телефона с зафиксированным кодом страны (+7)

;Ожидаем нажатия клавиши

again: mov ah,08h ;Функция ввода одиночного символа без эха

int 21h ;Первый вызов DOS

cmp al,0 ;Расширенный ASCII код?

mov ah,08h ;Да, введём старший байт

int 21h ;Повторный вызов DOS

cmp al,3B ;Нажата F1?

cmp al,54h ;Нажата ?

cmp al,1Eh ;Нажата ?

jmp again ;Нажато незапланированное

F1: ;Вывод сообщения mes1

Shift_F1: ;Вывод сообщения mes2

Alt_A: ;Вывод сообщения mes3

Exit: ;Завершение программы

7.2.5. СТРОКОВЫЕ КОМАНДЫ. ОБЩАЯ ХАРАКТЕРИСТИКА

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

Строковые команды, несмотря на синонимичное название со строковыми переменными, предназначены для обработки не только ASCII-строк, но и вообще блоков байтов, одинарных или двойных слов, каждое из которых хранится в памяти в двоичном коде.

Строковые команды представлены в табл. 3.1 и по своему назначению делятся на две группы:

— команды для поиска и сравнения данных (Scas, Cmps).

Любая строковая команда может оперировать как байтами, так и словами, что отражается в мнемокоде команды (например: movsb, movsw, movsd). Все строковые команды, в отличие от других команд процессора ix86, используют для выполнения своих функций одни и те же регистры:

Команды обработки строк

Название команды и её мнемокод

Действие

Тип исполь-зуемого префикса

Влияние на флаги

Lods src – Загрузка Acc из строки

src=byte ds:si Lodsb

src=word ds:si Lodsw

src=dword ds:si Lodsd

_

Stos dst – Сохранение Acc в строке

dst=byte es:di Stosb

dst=word es:di Stosw

dst=dword es:di Stosd

Movs dst,src Пересылка элемента строки

dst=byte es:di, src=byte ds:si Movsb

dst=word es:di, src=word ds:si Movsw

dst=dword es:di, src=dword ds:si Movsd

Scas dst – Поиск элемента в строке

dst=byte es:di Scasb

dst=word es:di Scasw

dst=dword es:di Scasd

Все флаги операции сравнения

Cmps dst, src Сравнение элементов строк

src=byte ds:si, dst=byte es:di Cmpsb

src=word ds:si, dst=word es:di Cmpsw

src=dword ds:si, dst=dword es:di Cmpsd

srcdst .


Все флаги операции сравнения

При этом индексные регистры si(esi) и di(edi) определяют смещения элементов строк в сегментах данных, определяемых регистрами ds и es соответственно. Установите es = ds, если это не противоречит другим условиям реализации программы, что позволит вам не беспокоиться о корректной адресации сегментов памяти. Необходимо помнить, что в строковых инструкциях приёмник – строка es:di(edi) не допускает переопределение, а источник – строка ds:si(esi), допускает переопределение на es:si(esi).

Каждая из строковых команд выполняет операцию только над парой элементов двух строк (или над одним для команд Lods, Stos, Scas) и автоматически настраивается на обработку соседних элементов, обеспечивая продвижение по строке в нужном направлении, а именно:

Здесь величина d определяется согласно правилу:

Тип операнда Флаг направления

Префикс повторения, помещённый непосредственно перед строковой командой, заставляет её циклически выполняться определённое число раз до реализации заданного условия. Существуют три командных префикса:

rep (repeat) – повторять, пока cx ¹ 0;

Префиксы используют регистр CX как счётчик числа циклов (беззнаковое число), которое должно быть записано в CX до начала выполнения строковой команды. Счётчик CX декрементируется на 1 после выполнения строковой команды, но проверяется перед её выполнением. Если CX = 0, то строковая команда не выполняется ни разу. Префиксы repe и repne дополнительно выставляют флаг нуля ZF после выполнения строковой операции.

В листинге 2.2. рассматривается использование строковой команды сравнения cmpsb на примере программы с паролем. Идея простейшей защиты программы от несанкционированного запуска заключается в том, что где-то в программе записывается ключевое слово-пароль, и программа, начав работать, требует ввода этого слова с клавиатуры. Если пользователь ввёл пароль правильно, программа продолжит свою работу, иначе попросит ввести его заново или завершится. Ввод пароля обычно осуществляется функцией DOS, не отображающей вводимые символы на экране (обычно 07h или 08h) и заканчивается нажатием клавиши .

Листинг 2.2. Фрагмент программы с паролем.

password DB ‘camel’ ;Пароль

string DB 80 DUP(?)

promt DB 13,10,’Введите пароль: $’

OK DB 13,10,’Работаем!$’

start: mov ax,@data

begin: mov ah,09h ;Вывод запроса на ввод пароля

mov dx,offset promt ;Адрес запроса

mov bx,0 ;Инициализация индексирования ввода

pass: mov ah,08h ;Функция ввода символа в AL без эха

je compare ;Да, на сравнение

mov [string+bx],al ;Нет, сохраним символ

mov dl,’*’ ;Запишем на экран *

jmp pass ;Повторять

;Сравнение введённого пароля с действительным (сравнение строк)

compare: push ds ;Установить ES на сегмент данных

mov si,offset string ;DS:SI- начало string

mov di,jffset password ;ES:DI- начало password

cld ;DF=0- просмотр вперёд

mov cx,pass_len ;Установить счётчик сравнения

repe cmpsb ;Сравнивать, пока (или повторять

;пока символы двух строк совпадают, но не более CX раз)

jne err ;Строки не равны

Вывод сообщения ОК, подтверждающего правильность пароля

mov dx,offset OK

exit: mov ax,4C00h ;Ввод функции 4С для завершения программы

err: jmp begin ;Повторить ввод пароля

Логика построения программы поясняется подробными комментариями. В программе ввод пароля выполняется в бесконечном цикле, поэтому пользователь, не знающий пароля и запустивший программу, для выхода из неё вынужден будет нажать комбинацию клавиш .

7.3. ЗАДАНИЯ К РАБОТЕ. ПОДГОТОВКА И ВЫПОЛНЕНИЕ

¨ Задания к работе

1) Ввести строку из произвольных ASCII-символов и произвести её сортировку под управлением функциональных клавиш: – по возрастанию; – по убыванию; – завершение программы. Работу программы отобразить на экране.

2) Ввести строку из произвольного числа символов и произвести в ней поиск подстроки SYMBOL. Если подстрока найдена, то её необходимо удалить. Вновь полученную строку вывести на экран. Если подстрока не найдена, вывести сообщение NOT_FOUND. Программу защитить паролем.

3) Ввести строку из произвольного числа символов. Выполнить преобразование символьной строки в её цифровой аналог на основе ASCII-кодов, после чего произвести поиск максимального кода. Работу программы отобразить на экране и защитить паролем.

4) Ввести строку из произвольных ASCII-символов и произвести её сортировку к виду, включающему четыре части разделённые пробелами: цифры, буквы прописные, буквы строчные, все другие символы. Работу программы отобразить на экране и защитить паролем.

5) Ввести строку из нескольких слов, разделённых пробелами. Слова включают в произвольном порядке цифры, строчные и прописные латинские буквы. Отредактированная строка включает слова, начинающиеся с прописной буквы (остальные строчные). Цифры из слов должны быть удалены. Программу защитить паролем.

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

7) Ввести строку из произвольного числа символов и произвести в ней поиск подстроки COMPUTER. Если такой подстроки нет, то данную подстроку ввести в начало исходной строки и вывести на экран. В противном случае дать сообщение There is. Программу защитить паролем.

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

9) Ввести строку из произвольного числа символов. Выполнить преобразование символьной строки в её цифровой аналог на основе ASCII-кодов, после чего произвести поиск минимального кода. Работу программы отобразить на экране и защитить паролем.

10) Ввод с клавиатуры на экран произвольного текста с одновременной записью в буфер. Реализовать элементы редактирования: стирание последних символов клавишей Backspace, контроль над прописной буквой первого слова нового предложения (ввести признак начала предложения). При ошибке строчная буква заменяется прописной. Переход на новую строку осуществляется клавишей . Управление: – вывод копии отредактированного текста из буфера, – выход из программы.

11) Ввод с клавиатуры на экран произвольного текста с одновременной записью в буфер. Программа демонстрирует переход на новую строку одним из двух способов:

– нажатие клавиши , если последнее введённое слово пересекло границу в 40 символов. В этом случае на новую строку автоматически переносится всё последнее слово. После перехода на новую строку вывод текста может быть продолжен в обычном порядке. Выход из программы с помощью клавиши .

12) Ввести строку из произвольного числа символов и произвести в ней поиск подстроки AUTOMATON. Если такой подстроки нет, то в начало исходной строки поместить символ @, а в её конец дописать подстроку и вывести на экран. В противном случае дать сообщение There is. Программу защитить паролем.

13) Программа проверки работоспособности ОЗУ для заданной области памяти данных с использованием шахматного теста. Тест предусматривает запись в ячейки с чётными адресами числа 0AAh, а в нечётные – 55h. В результате последующего считывания осуществляется проверка записанной информации. При обнаружении сбоя запоминается адрес данной ячейки (для проверки выполнения последнего требования использовать прогон программы в отладчике TD).

14) Программа проверки работоспособности ОЗУ для заданной области памяти с использованием сканирующего теста. Тест предусматривает запись байта 00h с последующим считыванием и проверкой, затем те же действия выполняются с числом 0FFh. По результатам теста формируется массив из адресов ячеек, в которых обнаружен сбой (для проверки выполнения последнего требования использовать прогон программы в отладчике TD). Программу оформить как com-файл.

15) Разработать программу, преобразующую все символы введённой строки (в строке представлены произвольные алфавитно-цифровые символы) из нижнего регистра клавиатуры в верхний.

¨ Подготовка и выполнение:

a) ознакомиться с методическими рекомендациями к лабораторной работе и соответствующими тематическими разделами в рекомендуемой литературе;

б) разработать и отладить программу в соответствии с индивидуальным заданием;

в) программа, по возможности, должна обеспечивать удобный экранный интерфейс с пользователем при её демонстрации;

г) отчёт о выплненной работе представляет собой:

– индивидуальное задание на разработку программы;

– листинг программы с подробными комментариями и описанием её работы.

7.4. КОНТРОЛЬНЫЕ ВОПРОСЫ

1. Что такое дескриптор? Сколько дескрипторов определено в DOS и как ими пользоваться?

2. Какие функции DOS можно использовать для ввода символов с клавиатуры в регистр AL процессора?

3. Назовите функции DOS, осуществляющие ввод строки символов с клавиатуры в память данных.

4. Какие функции DOS осуществляют операцию вывода на экран:

– одиночных символов из регистра DL процессора;

– строки символов из памяти данных?

5. Напишите процедуру перевода курсора на новую строку с помощью функции 02h DOS.

6. Что такое скан-код клавиши и чем он отличается от расширенного кода ASCII? Как нужно организовать вызовы соответствующей функции DOS для получения расширенного ASCII-кода?

7. Каким сегментным регистрам должен адресоваться сегмент данных, в котором располагается:

8. Какие строковые команды влияют на флаги, а какие нет?

9. Перечислите префиксы повторения строковых команд и их возможные сочетания друг с другом.

10. В какой фазе исполнения команды происходит проверка счётчика на равенство нулю при выполнении:

– строковой команды с префиксом повторения;

– команды управления циклом Loop ?

Что происходит с исполнением этих команд, если счётчик СХ инициализирован нулём?

2. КЛАВИАТУРА

В этом разделе мы подробно рассмотрим одно из важнейших устройств персонального компьютера — клавиатуру. Практически ни одна программа не обходится без обращения к клавиатуре.

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

Мы расскажем о работе с клавиатурой на разных уровнях — от использования клавиатурных портов ввода/вывода до средств, предоставляемых стандартными библиотеками трансляторов Microsoft QC 2.5 и C 6.0. Какой уровень вам следует выбрать, зависит от решаемой задачи. Единственное, что можно порекомендовать — это использовать по возможности средства высокого уровня. Если ваша программа работает с клавиатурой на уровне портов ввода/вывода, ее работа может оказаться зависимой от типа клавиатуры и от типа компьютера.

Клавиатура выполнена, как правило, в виде отдельного устройства, подключаемого к компьютеру тонким кабелем. Малогабаритные компьютеры Lap-Top используют встроенную клавиатуру.

Что же находится внутри клавиатуры? Оказывается, там есть компьютер! Только этот компьютер состоит из одной микросхемы и выполняет специализированные функции. Он отслеживает нажатия на клавиши и посылает номер нажатой клавиши в центральный компьютер.

Если рассмотреть сильно упрощенную принципиальную схему клавиатуры, представленную на рисунке, можно заметить, что все клавиши находятся в узлах матрицы:

Рис.1. Упрощенная схема клавиатуры


Все горизонтальные линии матрицы подключены через резисторы к источнику питания +5 В. Клавиатурный компьютер имеет два порта — выходной и входной. Входной порт подключен к горизонтальным линиям матрицы (X0-X4), а выходной — к вертикальным (Y0-Y5).

Устанавливая по очереди на каждой из вертикальных линий уровень напряжения, соответствующий логическому 0, клавиатурный компьютер опрашивает состояние горизонтальных линий. Если ни одна клавиша не нажата, уровень напряжения на всех горизонтальных линиях соответствует логической 1 (т.к. все эти линии подключены к источнику питания +5 В через резисторы).

Если оператор нажмет на какую-либо клавишу, то соответствующая вертикальная и горизонтальная линии окажутся замкнутыми. Когда на этой вертикальной линии процессор установит значение логического 0, то уровень напряжения на горизонтальной линии также будет соответствовать логическому 0.

Как только на одной из горизонтальных линий появится уровень логического 0, клавиатурный процессор фиксирует нажатие на клавишу. Он посылает в центральный компьютер запрос на прерывание и номер клавиши в матрице. Аналогичные действия выполняются и тогда, когда оператор отпускает нажатую ранее клавишу.

Номер клавиши, посылаемый клавиатурным процессором, однозначно связан с распайкой клавиатурной матрицы и не зависит напрямую от обозначений, нанесенных на поверхность клавиш. Этот номер называется скан-кодом (Scan Code).

Слово scan («сканирование»), подчеркивает тот факт, что клавиатурный компьютер сканирует клавиатуру для поиска нажатой клавиши.

Но программе нужен не порядковый номер нажатой клавиши, а соответствующий обозначению на этой клавише ASCII-код. Этот код не зависит однозначно от скан-кода, т.к. одной и той же клавише могут соответствовать несколько значений ASCII-кода. Это зависит от состояния других клавиш. Например, клавиша с обозначением ‘1’ используется еще и для ввода символа ‘!’ (если она нажата вместе с клавишей SHIFT).

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

Если нажать на клавишу и не отпускать ее, клавиатура перейдет в режим автоповтора. В этом режиме в центральный компьютер автоматически через некоторый период времени, называемый периодом автоповтора, посылается код нажатой клавиши. Режим автоповтора облегчает ввод с клавиатуры большого количества одинаковых символов.

Следует отметить, что клавиатура содержит внутренний 16-байтовый буфер, через который она осуществляет обмен данными с компьютером.

В настоящее время существует три различных типа клавиатуры. Это клавиатура для компьютеров IBM PC/XT, 84-клавишная клавиатура для IBM AT и 101-клавишная (расширенная) клавиатура для IBM AT. Некоторые клавиатуры имеют переключатель режима работы (XT/AT), расположенный на нижней крышке. Он должен быть установлен в правильное положение.

Для работы с клавиатурой типа PC/XT используются порты с адресами 60h и 61h.

Порт 60h при чтении содержит скан-код последней нажатой клавиши.

Порт 61h управляет не только клавиатурой, но и другими устройствами компьютера, например, работой встроенного динамика. Этот порт доступен как для чтения, так и для записи. Для нас важен самый старший бит этого порта. Если в старший бит порта 61h записать значение 1, клавиатура будет заблокирована, если 0 — разблокирована.

Так как порт 61h управляет не только клавиатурой, при изменении содержимого старшего бита необходимо сохранить состояние остальных битов этого порта. Для этого можно сначала выполнить чтение содержимого порта в регистр, изменить состояние старшего бита, затем выполнить запись нового значения в порт:

Компьютер типа IBM AT позволяет управлять скоростными характеристиками клавиатуры, а также зажигать или гасить светодиоды на лицевой панели клавиатуры — Scroll Lock, Num Lock, Caps Lock.

Для расширенного управления клавиатурой используется порт 60h в режиме записи. Этот порт используются для управления подчиненным процессором Intel 8042, ответственным за обмен данными с клавиатурным компьютером.

При использовании порта 60h на запись программа дополнительно получает следующие возможности:

  • установка времени ожидания перед переходом клавиатуры в режим автоповтора;
  • установка периода генерации скан-кода в режиме автоповтора;
  • управление светодиодами, расположенными на лицевой панели клавиатуры — Scroll Lock, Num Lock, Caps Lock.

Процессор 8042 обслуживает не только клавиатуру, но и другие системы компьютера. Через порт 64h, например, выполняется сброс (отключение) процессора 80286 для возврата из защищенного режима работы в реальный.

Для посылки команды процессору 8042 вначале необходимо убедиться в том, что его внутренняя очередь команд пуста. Это можно сделать, прочитав слово состояния 8042 из порта с адресом 64h. Бит с номером 1 должен быть равен нулю.

Приведем фрагмент программы, составленной на языке ассемблера, проверяющий состояние очереди команд процессора 8042:

После того, как программа дождется готовности процессора 8042, она может послать ему команду, записав ее в порт с адресом 60h:

Некоторые команды состоят более чем из одного байта. Остальные байты команды необходимо записать в порт 60h, предварительно убедившись в готовности процессора 8042 с помощью последовательности команд, приведенной выше. В большинстве случаев можно также использовать простую временную задержку:

Мы приведем формат двух команд процессора 8042, имеющих отношение к работе с клавиатурой — команду установки задержки и периода автоповтора и команду управления светодиодами, расположенными на клавиатуре.

Для установки характеристик режима автоповтора в порт 60h необходимо записать код команды 0F3h, затем байт, определяющий характеристики режима:

Первоначально при инициализации системы период задержки для включения режима автоповтора устанавливается модулями BIOS равным 500 мс при периоде автоповтора, равном 10 повторам в секунду. Если это слишком медленно для вас, вы можете установить другие значения. Некоторые прикладные программы, например, текстовый процессор Microsoft Word, содержат средства для управления временными характеристиками клавиатуры.

Для управления светодиодами, расположенными на лицевой панели клавиатуры, используйте команду 0EDh. Вслед за этой командой в порт 60h необходимо записать байт, имеющий следующий формат:

Приведем пример простейшей программы, управляющей светодиодами на лицевой панели компьютера. Такое управление может выполняться только при использовании порта 60h управления клавиатурой, так как BIOS не содержит соответствующей поддержки. Наша программа после запуска включит все светодиоды и будет ожидать нажатия на любую клавишу. После нажатия программа выключит светодиоды.

Клавиатура подключена к линии прерывания IRQ1. Этой линии соответствует прерывание INT 09h.

Клавиатурное прерывание обслуживается модулями BIOS. Драйверы клавиатуры и резидентные программы могут организовывать дополнительную обработку прерывания INT 09h. Для этого может быть использована цепочка обработчиков прерывания. В первой книге первого тома мы приводили примеры расширения обработчика прерывания INT 09h.

Как работает стандартный обработчик клавиатурного прерывания, входящий в состав BIOS?

Этот обработчик выполняет следующие действия:

  • читает из порта 60h скан-код нажатой клавиши;
  • записывает вычисленное по скан-коду значение ASCII-кода нажатой клавиши в специальный буфер клавиатуры, расположенный в области данных BIOS;
  • устанавливает в 1 бит 7 порта 61h, разрешая дальнейшую работу клавиатуры;
  • возвращает этот бит в исходное состояние;
  • записывает в порт 20h значение 20h для правильного завершения обработки аппаратного прерывания.

Обработчик прерывания INT 09h не просто записывает значение ASCII-кода в буфер клавиатуры. Дополнительно отслеживаются нажатия таких комбинаций клавиш, как Ctrl-Alt-Del, обрабатываются специальные клавиши PrtSc и SysReq. При вычислении кода ASCII нажатой клавиши учитывается состояние клавиш Shift и CapsLock.

Буфер клавиатуры имеет длину 32 байта и расположен по адресу 0000h:041Eh для машин IBM PC/XT.

В IBM AT и PS/2 расположение клавиатурного буфера задается содержимым двух слов памяти с адресами 0000h:0480h (компонента смещения адреса начала буфера) и 0000h:0482h (смещение конца буфера). Обычно в IBM AT эти ячейки памяти содержат значения, соответственно, 001Eh и 003Eh. Так как смещения заданы относительно сегментного адреса 0040h, то видно, что обычное расположение клавиатурного буфера в IBM AT и PS/2 соответствует его расположению в IBM PC/XT.

Клавиатурный буфер организован циклически. Это означает, что при его переполнении самые старые значения будут потеряны. Две ячейки памяти, находящиеся в области данных BIOS с адресами 0000h:041Ah и 0000h:041Ch содержат, соответственно, указатели на начало и конец буфера. Если значения этих указателей равны друг другу, буфер пуст. (Можно удалить все символы из буфера клавиатуры, установив оба указателя на начало буфера. Однако есть более предпочтительный способ с использованием прерывания BIOS INT 16h).

Указателями на начало и конец клавиатурного буфера обычно управляют обработчики прерываний INT 09h и INT 16h.

Программа извлекает из буфера коды нажатых клавиш, используя различные функции прерывания INT 16h.

Помимо управления содержимым буфера клавиатуры, обработчик прерывания INT 09h отслеживает нажатия на так называемые переключающие клавиши — NumLock, ScrollLock, CapsLock, Ins. Состояние этих клавиш записывается в область данных BIOS в два байта с адресами 0000h:0417h и 0000h:0418h.

Формат байта 0000h:0417h:

Формат байта 0000h:0418h:

Если вы изменяете состояние светодиодов на панели клавиатуры, не забывайте устанавливать соответствующие биты в байтах состояния клавиатуры.

Программой обработки прерывания INT 09h отслеживаются некоторые комбинации клавиш. В таблице приведены эти комбинации и действия, выполняемые обработчиком прерывания при их обнаружении:

Многие типы клавиатур имеют отдельную альтернативную цифровую панель, напоминающую клавиатуру калькулятора. Если одновременно с нажатием на клавишу Alt набрать число на этой панели (не большее, чем 255 и не равное 0), то это число будет помещено в буфер клавиатуры, как будто бы оно было введено нажатием на одну клавишу. Это число будет также записано в слове по адресу 0000h:0419h в области данных BIOS.

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

При составлении программ для MS-DOS у вас едва ли появится необходимость непосредственного манипулирования содержимым буфера клавиатуры — вы можете использовать прерывание BIOS INT 16h для выполнения практически всех клавиатурных операций.

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

Набор функций для работы с клавиатурой, предоставляемый в распоряжение программиста прерыванием BIOS INT 16h, включает в себя функции для выборки кода нажатого символа из буфера с ожиданием нажатия, функции для проверки содержимого буфера и для управления содержимым буфера, функции для изменения скоростных характеристик клавиатуры.

Функция 00h выполняет чтение кода символа из буфера клавиатуры, если он там есть. Если буфер клавиатуры пуст, программа переводится в состояние ожидания до тех пор, пока не будет нажата какая-нибудь клавиша. Скан-код и ASCII-код нажатой клавиши передаются программе.

Приведем формат вызова функции:

Приведем таблицу скан-кодов для клавиатуры IBM PC/XT:

Для остальных клавиш функция 00h прерывания INT 16h возвращает расширенный ASCII-код:

В следующей таблице приведены скан-коды клавиш, имеющихся только на 101-клавишной клавиатуре:

Буква «Д» в последней таблице обозначает дополнительную («калькуляторную») клавиатуру.

Для демонстрации использования функции 00h прерывания INT 16h мы подготовили программу, выводящую на экран скан-коды и ASCII-коды нажимаемых клавиш:

Функция 01h поможет вам проверить состояние буфера клавиатуры — есть там коды нажатых клавиш или нет. При этом программа не переводится в состояние ожидания, даже если буфер клавиатуры пуст. В этом случае в регистре флагов устанавливается в единицу флаг ZF и управление возвращается программе.

Эту функцию удобно использовать во время выполнения какого-либо длительного процесса (например, форматирования диска или передачи данных по линии связи) для прерывания этого процесса по запросу оператора.

Кроме того, функцию можно использовать вместе с функцией 00h для сброса содержимого клавиатурного буфера. Для этого в цикле повторяют вызов функции 01h, вслед за которым идет вызов функции 00h при условии, что буфер клавиатуры не пуст. Сброс клавиатурного буфера полезно выполнять перед вводом ответственной информации, так как из-за случайного двойного или тройного нажатия на клавишу в буфере клавиатуры могут оказаться лишние символы.

Приведем текст программы, выводящей на экран в цикле символ ‘*’. При нажатии на любую клавишу, кроме ESC, программа выводит на экран строку текста — инструкцию для завершения работы программы. Если нажать на клавишу ESC, работа программы будет завершена.

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins). Формат байта состояния соответствует формату байта, находящегося в области данных BIOS по адресу 0000h:0417h:

Функция может быть использована для анализа текущего состояния переключающих клавиш.

Изменим текст предыдущей программы таким образом, чтобы завершение ее работы происходило лишь в том случае, если переключающая клавиша CapsLock находится в выключенном состоянии (соответствующий светодиод не горит):

Мы уже рассказывали о возможности изменения временных характеристик клавиатуры. Если BIOS, установленная в вашей машине, изготовлена после 15 декабря 1985 года, вы можете воспользоваться этой функцией для ускорения (или замедления) работы клавиатуры.

В качестве примера приведем две программы. Первая программа увеличивает быстродействие клавиатуры до его верхнего предела, вторая восстанавливает исходные значения временных характеристик.

С помощью этой функции можно вставить символы в буфер клавиатуры, как будто они были введены оператором.

Приведенная программа записывает в буфер клавиатуры пять символов ‘*’. Запустите ее и посмотрите на системное приглашение. Вы увидите что-нибудь похожее на C:>*****.

Функция 10h полностью аналогична функции 00h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Приведем формат вызова функции:

Функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

Функция 11h полностью аналогична функции 01h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins):

Функция 12h аналогична функции 02h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу и имеет другой формат байта состояния.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

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

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

Кроме того, некоторые клавиатурные функции автоматически посылают введенные символы на устройство стандартного вывода. По умолчанию это дисплей, но устройство стандартного вывода может быть переназначено для вывода в файл, на принтер или другое устройство.

Вообще говоря, клавиатурные функции MS-DOS больше всего подходят для тех программ, которые ведут с оператором «построчный» диалог. Для таких программ при использовании средств переназначения ввода/вывода возможна организация автоматического «пакетного» выполнения, когда все сообщения выводятся в файл, а все данные, которые обычно вводятся с клавиатуры, считываются из заранее подготовленного файла «ответов».

Некоторые клавиатурные функции MS-DOS отслеживают комбинации клавиш Ctrl-C и Ctrl-Break. Если оператор ввел такую комбинацию клавиш, вызывается прерывание INT 23h, завершающее работу текущей программы. Если ваша программа не должна завершаться при нажатии этих комбинаций клавиш, можно либо создать и подключить собственный обработчик для INT 23h, либо использовать те клавиатурные функции MS-DOS, которые не выполняют проверку указанных выше комбинаций клавиш.

Приведем подробное описание клавиатурных функций прерывания MS-DOS INT 21h.

Функция читает символы со стандартного устройства ввода. Если стандартным устройством ввода является клавиатура, и буфер клавиатуры пуст, выполнение программы задерживается до нажатия на любую клавишу.

Введенный символ выводится на стандартное устройство вывода.

Если программа в качестве ASCII-кода получила 0, она должна вызвать эту функцию еще один раз. Во второй раз регистр AL будет содержать расширенный ASCII-код нажатой клавиши.

Функция аналогична предыдущей. Она читает символы со стандартного устройства ввода. Если стандартным устройством ввода является клавиатура, и буфер клавиатуры пуст, выполнение программы задерживается до нажатия на любую клавишу.


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

Если буфер клавиатуры пуст, выполнение программы задерживается до нажатия на любую клавишу.

Эту функцию удобно использовать в тех случаях, когда завершение программы по нажатию комбинаций клавиш Ctrl-C или Ctrl-Break по тем или иным причинам нежелательно. Например, программа держит в оперативной памяти буфера для данных, которые перед завершением работы обязательно должны быть записаны на диск. Если оператор в неподходящий момент времени нажал Ctrl-C и программа аварийно завершила работу, содержимое буферов будет потеряно.

Функция 06h может использоваться как для ввода с консоли, так и для вывода символов на консоль. Режим работы функции зависит от содержимого регистра DL при вызове функции. Если этот регистр содержит значение 0FFh, функция выполняет ввод с консоли, в противном случае символ, код которого записан в этот регистр, выводится на консоль.

Очевидно, что с помощью этой функции нельзя вывести на консоль символ с кодом 0FFh.

Основное отличие функции 06h от всех описанных ранее заключается в том, что эта функция не ожидает, пока оператор нажмет на клавишу. Если буфер клавиатуры пуст, функция просто устанавливает флаг процессора ZF в 1.

Если в буфере клавиатуры имеются символы, флаг ZF сбрасывается и в регистр AL функция записывает ASCII-код символа.

Функция предназначена для ввода с клавиатуры строки символов. Перед вызовом функции необходимо специальным образом подготовить буфер, адрес которого передается в регистрах DS:DX — в первый байт буфера следует записать максимальную длину вводимой строки (в диапазоне от 1 до 244):

После возврата из функции буфер будет иметь следующий формат:

Ввод осуществляется до тех пор, пока либо количество введенных символов не достигнет max-1, либо пока не будет нажата клавиша Enter (код 0Dh). Если оператор уже ввел max-1 символ и продолжает вводить символы дальше, функция выдает звуковой сигнал на каждое нажатие и игнорирует вводимые символы до тех пор, пока не будет нажата клавиша Enter.

При вводе строки можно использовать стандартные средства редактирования MS-DOS, используемые при вводе команд в режиме командной строки.

Эта функция проверяет состояние клавиатурного буфера. Вы можете вызывать ее перед функциями 01h, 07h, 08h для того, чтобы избежать ожидания нажатия на клавишу.

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

Функция очищает клавиатурный буфер, затем вызывает клавиатурную функцию MS-DOS, номер которой определяется содержимым регистра AL. Если же регистр AL содержит другое значение, кроме приведенных выше, функция просто сбрасывает содержимое буфера и не выполняет никаких других действий.

Эту функцию удобно использовать тогда, когда перед вводом символа необходимо убедиться в том, что буфер клавиатуры пуст.

Стандартные библиотеки трансляторов Microsoft QuickC и C 6.0 содержат набор функций, предназначенных для работы с клавиатурой. Эти функции повторяют и немного дополняют возможности функций MS-DOS и BIOS, обслуживающих клавиатуру.

Самые простые из них — getch() и getche(). Они описаны в файле conio.h.

Функция getch() имеет следующий прототип:

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

Функция обрабатывает клавиши Ctrl-С и Ctrl-Break — при вводе этих комбинаций клавиш работа программы завершается.

Если клавиатурный буфер пуст, программа переводится в состояние ожидания.

Функция getche() полностью аналогична функции getch(), за исключением того, что прочитанный символ отображается на экране. Приведем прототип функции getche():

Приведем пример программы, отображающей на экране ASCII-коды и расширенные ASCII-коды нажимаемых клавиш:

Для проверки буфера клавиатуры на наличие символов можно использовать функцию kbhit(). Она также описана в файле conio.h:

Если буфер клавиатуры не пуст, функция возвращает ненулевое значение. В этом случае программа может прочитать символы из буфера клавиатуры при помощи фукнкций getch() и getche(). Если буфер клавиатуры пуст, функция возвращает нулевое значение.

Приведем пример программы, ожидающей нажатия на любую клавишу. Во время ожидания программа выводит на экран поочередно символы » «:

Для ввода с клавиатуры строки символов можно использовать функцию cgets(), работающую аналогично функции 0Ah прерывания MS-DOS INT 21h:

Функция описана в файле conio.h.

Перед вызовом аргумент функции buffer должен указывать на массив, размер которого должен быть достаточным для хранения вводимой строки, завершающего строку нулевого байта и двух дополнительных байтов. Первый элемент массива buffer[0] должен содержать максимальную длину вводимой строки — как и для функции 0Ah прерывания MS-DOS INT 21h.

После завершения ввода второй элемент массива buffer[1] будет содержать длину введенной строки, сама строка будет завершаться символами новой строки NL, перевода строки LF и нулем.

Функция cgets() возвращает указатель на начало введенной строки в буфере, т.е. на третий элемент массива buffer[2].

Приведем простой пример, в котором функция cgets() используется для ввода целого числа:

Существует и более удобная для использования функция, позволяющая вводить строку с клавиатуры, а точнее, из стандартного потока ввода. Это функция gets():

Функция gets() описана в файле stdio.h.

Эта функция читает строку из стандартного потока ввода stdin и запоминает ее в буфере buffer. Символ новой строки n в конце введенной строки функция заменяет на ноль.

После завершения ввода функция возвращает указатель на заполненный буфер или NULL в случае ошибки или условия «Конец файла».

Обратим ваше внимание на отличия между функциями cgets() и gets():

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

Еще одна полезная функция, которую можно использовать для ввода с клавиатуры — scanf(). Эта функция подробно описана во всех книгах по языку программирования Си, поэтому мы не будем ее подробно рассматривать. Отметим только, что с помощью этой функции можно организовать ввод чисел в заданном формате. Однако можно сначала ввести строку при помощи функций cgets() или gets(), а уже потом выполнять все необходимые проверки и преобразования этой строки.

*.bat файл с вводом с клавиатуры

Все новые темы

_________________
Мы спpосили у десяти пpохожих:
— Что такое TCP/IP?
Девять из десяти ответили что не знают. И только один человек сpазу послал нас на х$й.
Вернуться к началу
Vlad.S
Почетный житель

Зарегистрирован: 23.12.2006
Пользователь #: 48,870
Сообщения: 3146

Голоса: 28

Добавлено: Сб 11 Апр, 2009 17:33 Заголовок сообщения:
Вернуться к началу gregor
Новичок

Зарегистрирован: 15.06.2004
Пользователь #: 18,149
Сообщения: 2
Откуда: Tyachiv

Добавлено: Вс 12 Апр, 2009 1:36 Заголовок сообщения:
Вернуться к началу Aerus
Новичок

Зарегистрирован: 21.05.2008
Пользователь #: 69,289
Сообщения: 13

Добавлено: Вс 12 Апр, 2009 10:41 Заголовок сообщения:
Вернуться к началу BuHast
Активный участник

Зарегистрирован: 23.10.2006
Пользователь #: 44,874
Сообщения: 598

Голоса: 2

Добавлено: Вс 12 Апр, 2009 13:26 Заголовок сообщения:
_________________
Мы спpосили у десяти пpохожих:
— Что такое TCP/IP?
Девять из десяти ответили что не знают. И только один человек сpазу послал нас на х$й.
Вернуться к началу BuHast
Активный участник

Зарегистрирован: 23.10.2006
Пользователь #: 44,874
Сообщения: 598

Голоса: 2

Добавлено: Пн 13 Апр, 2009 11:35 Заголовок сообщения:
_________________
Мы спpосили у десяти пpохожих:
— Что такое TCP/IP?
Девять из десяти ответили что не знают. И только один человек сpазу послал нас на х$й.
Вернуться к началу Vlad.S
Почетный житель

Зарегистрирован: 23.12.2006
Пользователь #: 48,870
Сообщения: 3146

Голоса: 28

Добавлено: Пн 13 Апр, 2009 12:32 Заголовок сообщения:
Вернуться к началу ipmanyak
Windows guru
Windows guru » title=» Windows guru » border=»0″ />

Зарегистрирован: 28.03.2007
Пользователь #: 53,638
Сообщения: 3301

Голоса: 54

Добавлено: Пн 13 Апр, 2009 12:38 Заголовок сообщения:
_________________
В сортире лучше быть юзером, а не админом!
Вернуться к началу BuHast
Активный участник

Зарегистрирован: 23.10.2006
Пользователь #: 44,874
Сообщения: 598

Ввод информации с клавиатуры средствами 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; Нарушение авторского права страницы

Системные функции DOS для работы с клавиатурой

Функции DOS для чтения с клавиатуры различаются, главным образом, по трем признакам:

а) ожидают ли ввода или нет;

б) выводят ли после чтения символ на экран;

в) проверяется ли при их выполнении наличие «Ctrl-Break» или нет.

Ввод с клавиатуры с эхоотображением

Функция 01h ожидает ввода символа, если буфер клавиатуры пуст, а затем выводит его на экран в текущую позицию курсора. Введенный символ помещается в регистр AL. Если AL содержит 00Н, это означает, что получен расширенный ASCII-код, второй байт которого будет прочитан при следующем выполнении функции. При выполнении функции осуществляется проверка наличия «Ctrl-Break». Клавиша Esc игнорируется. Клавиша Backspace сдвигает курсор на одну позицию влево, но символ, находящийся в этой позиции, не стирается. Клавиша Enter вызывает перемещение курсора в первую позицию текущей строки (нет автоматического перевода строки).

MOV AH,01h ; номер функции

INT 21h ; ожидаем нажатия клавиши

CMP AL,0 ; расширенный код ?

JE EXT_CODE ; если да, то на процедуру обработки

EXT_CODE: INT 21h ; получаем в AL номер кода

CMP AL,77 ; проверка на ()

JNE C_R ; если нет, то следующая проверка

JMP CUR_RIT ; если да, то на процедуру

C_R: CMP AL,75 ; и т.д.

Ввод символа без ожидания

Некоторые программы, работающие в реальном времени, не могут останавливаться и ждать нажатия клавиши. Такие программы принимают символ из буфера, только тогда, когда это им удобно, например, это игровые программы.

Функция 6 прерывания 21h – единственный способ получить введенный символ без ожидания. Эта функция не дает эха на экране и не распознает Ctrl-Break. Перед вызовом прерываний в DL должно быть помещено FFh. Иначе функция 6 будет печатать символ, находящийся в DL в текущую позицию курсора. Если символ принят, то он помещается в AL. Нулевое значение говорит о расширенном коде, и прерывание должно быть повторено.

MOV AH,6 ; номер функции

MOV DL,FFh ; запрос ввода с клавиатуры

INT 21H ; получение символа

JZ NO_CHAR ; переход, если нет символа

CMP AL,0 ; проверка на расширенный код

JE EXT_COD ; переход,если расширенный код

EXT_COD: INT 21h

Прямой ввод с клавиатуры без эхо

Функции 7 и 8 прерывания 21h ожидают ввода символа, если буфер клавиатуры пуст. Появление символа на экране не отображается. При этом функция 8 распознает Ctrl-Break, а функция 7 не реагирует на него. В обоих случаях символ возвращается в AL. Когда в AL содержится 0, получен расширенный код. Нужно повторить прерывание, и в AL появится второй байт расширенного кода.

MOV AH,7 ; номер функции

INT 21h ; ожидаем ввод символа

CMP AL,0 ; проверка на расширенный код

JE EXT_COD ; переход на процедуру, иначе код

Проверка состояния клавиатуры

Функция 0B помещает значение FF в регистр AL, если буфер клавиатуры содержит один или более символов, и значение 0, когда буфер пуст.

MOV AH,0Bh ; номер функции

INT 21h ; вызываем прерывание

CMP AL,FFh ; сравниваем с FF

JE GET_KEY ; переход, если буфер не пуст

Получение строки символов

Функция 0A позволяет вводить строку длиной до 254 символов, выдавая эхо на экран. Эта функция продолжает ввод поступающих символов до тех пор, пока не нажата клавиша Enter. DS:DX указывает на адрес памяти, куда должна быть помещена строка. Первый байт в этой позиции должен содержать число байтов, отводимых для этой строки. После того как строка введена, второй байт даст число реально введенных символов. Сама строка начинается с третьего байта.

MOV AX,5000h ; указываем адрес области данных

MOV AL,51 ; указываем длину строки

MOV [BX],AL ; заполняем первый байт

MOV AH,0Ah ; номер функции

INT 21h ; получаем строку

Эта функция выполняет команды редактирования строки. Нажатие клавиши Backspace или «стрелка-влево» удаляет символ с экрана без помещения его в память. Расширенные коды игнорируются, пустые строки допускаются (имеется в виду клавиша Enter, которой не предшествует другой символ). Когда вводится больше символов, чем отведено места для строки, лишние символы игнорируются, и включается гудок динамика.

Очистка буфера клавиатуры и ввод символа

Функция 0С выполняет любую из функций ввода с клавиатуры 1,6,7,8 и A, но перед этим чистит буфер клавиатуры. Надо просто поместить номер функции ввода в AL.

MOV AH,0Ch ; номер функции

MOV AL,1 ; выбираем функцию ввода символа

INT 21h ; чистим буфер,ждем ввода

Установка позиции курсора

Функция 02h прерывания 10h устанавливает курсор в любую позицию на экране в соответствии с координатами строки и столбца. Номер страницы обычно равен 0, но может иметь значение от 0 до 3 при 80 столбцах на экране. Для установки позиции курсора необходимо занести в регистр AH значение 02, в регистр BH – номер страницы и в регистр DX – координаты строки и столбца.

MOV AH,02 ; номер функции

MOV BH, 00 ; номер страницы

MOV DH,строка ; номер строки


MOV DL,столбец ; номер столбца

INT 10h ; устанавливаем курсор

Очистка экрана

Выведенная на экран информация остается на экране до тех пор, пока не будет смещена в результате прокручивания или замене на на том же месте другой информацией. Когда программа пользователя начинает свое выполнение, экран может быть очищен. Очищаемая область экрана может начинаться в любой позиции и заканчиваться в любой другой позиции с большим номером. Начальное значение строки и столбца заносится в регистр CX, конечное – в DX, значение 07 в регистр BH и 0600h в AX. В следующем примере выполняется очистка всего экрана:

MOV AX,0600h ; AH=06 (прокрутка), AL=00 (весь экран)

MOV BH,07 ; нормальный атрибут

MOV CX,0000 ; верхняя левая позиция

MOV DX,184Fh ; нижняя правая позиция

INT 10h ; передача управления в BIOS

Значение 06 в регистре AH указывает на выполнение операции очистки экрана. Эта операция очищает экран пробелами. В регистр AL заносится число сдвигаемых строк (00 — весь экран). CH и CL содержат строку и столбец левого верхнего угла, а DH и DL –строку и столбец правого нижнего угла. Появляющиеся из-за сдвига строки чистые, они выводятся с кодом атрибутов из BH.

Порядок выполнения работы

1. Напишите и выполните, пользуясь отладчиком DEBUG, команды для установки курсора по координатам: строка 20, столбец 58.

2. Напишите и выполните, пользуясь отладчиком DEBUG, команды для очистки экрана, начиная с 0-го столбца 12 строки, до 79-го столбца 22-й строки.

3. Пользуясь отладчиком DEBUG, введите с клавиатуры дату в формате дд/мм/гг в центре предварительно очищенного экрана.

4. Используя отладчик DEBUG, проверьте воздействие на содержимое регистра AX нажатие клавиш на клавиатуре. Для этого введите следующие команды:

Используя команду U 100,104, дисассемблируете программу и с помощью G 104 выполните команды MOV и INT. Выполнение программы остановится, и процессор перейдет в ожидание ввода. Для проверки регистра AH нажмите любую клавишу. Нажимая различные клавиши, проверьте работу этой программы.

5. Напишите и выполните программу, которая переводит курсор в 24 строку и нулевой столбец, если нажата клавиша PgDn.

Требования к отчету

Отчет по лабораторной работе должен содержать:

а) титульный лист;

б) условие задания;

в) текст программ на языке Ассемблера;

г) ответы на контрольные вопросы.

Контрольные вопросы

1. Какие шестнадцатеричные значения строки и столбца соответствуют нижнему правому углу экрана?

2. В какие регистры помещается скэн-код и код символа при нажатии символьной клавиши?

3. Какая информация будет находиться в регистре AL после нажатии функциональной клавиши?

Список литературы

1. Абель П. Ассемблер. Язык и программирование для IBM PC: пер с англ. – К.: Век+, 2005. – 736 с.

2. Рудольф М. Ассемблер на примерах. Базовый курс – М.: Наука и техника, 2005. – 240 с.

3. Пильщиков В. Assembler. Программирование на языке Ассемблера IBM PC – М.: Диалог-МИФИ, 2005. – 288 с.

4. Финогенов К. Г. Основы языка Ассемблера. – М.: Радио и связь, 2000. – 288 с.

5. Голубь Н.Г. Искусство программирования на Ассемблере Platinum Edition (3 изд.) –М.: Диасофт-ЮП, 2005. – 832 с.

Программа DEBUG

DOS-программу DEBUG можно применять для написания совсем небольших программ, для отладки программ, или для просмотра содержимого файла либо памяти. Удобнее всего запустить DEBUG в отдельном окне. Пользуясь командами из системного меню окна, можно копировать фрагменты его содержимого в буфер обмена или вставлять текст из буфера в окно.

Для запуска DEBUG из командной строки наберите DEBUG и нажмите . DEBUG загрузится с диска в память. Когда символ-приглашение появится на экране, DEBUG будет готов воспринимать команды (приглашение представляет собой дефис).

DEBUG можно запускать двумя способами:

1. DEBUG без указания аргументов, чтобы просмотреть содержимое памяти или создать новый файл.

2. DEBUG , чтобы отладить или модифицировать существующую программу.

Загрузчик программ размещает DEBUG в памяти, и DEBUG выводит дефис (–) в качестве приглашения. Регистры CS, DS, ES и SS инициализированы адресом 256-байтового (100Н) префикса сегмента программы (PSP), а рабочая область в памяти начинается с адреса PSP + 100Н. DEBUG отображает значения флагов следующим образом:

Перепол-нение OF Направ-ление F Прерыва-ние IF Знак SF Нуль ZF Вспомог. перенос AF Четность PF Перенос CF
1 0 OV NV DN UP EI DI NG PL ZR NZ AC NA PE PO CY NC

Ссылка на память может задаваться в виде сегмент:смещение, например, DS:120, или в виде только смещения, например, 120. Можно также напрямую обращаться к адресам в памяти, например, 40:17, где 40[0]Н – адрес начала сегмента, а 17Н — смещение. Сегмент данных для программ типа .ЕХЕ начинается с адреса DS:0, а для программ типа .СОМ – с DS:100.

DEBUG воспринимает все вводимые числа как шестнадцатеричные, т.е. вводить завершающую букву Н не нужно. Клавиша F1 воспроизводит последнюю команду по одной букве за нажатие, a F3 – целиком. Кроме того, DEBUG не различает строчные и заглавные буквы.

Далее в алфавитном порядке перечислены команды DEBUG.

A (Assemble)

Транслирует ассемблерные команды в машинный код. Операция используется для написания и тестирования маленьких программ на ассемблере и для изучения небольших фрагментов кода. Адрес начала кода по умолчанию – CS:100H. Формат команды: а [адрес], где адрес по умолчанию – 100Н.

DEBUG поддерживает следующие возможности:

• определение элементов данных в программах с помощью DB и DW;

• операнд в квадратных скобках, например, [12Е], указывает адрес (смещение) в памяти;

• оператор PTR можно использовать для указания байта или слова, например, INC BYTE PTR[12E].

Можно применять все виды косвенной адресации с использованием регистров, например, [BP+DI] или 25[ВХ].

Ниже приведен пример создания маленькой ассемблерной программы из пяти инструкций. Вводить нужно только инструкции; DEBUG указывает адрес сегмента кода (показанный здесь в виде хххх:) и смещения, начиная со 100Н:

А (или А 100) ;Начать ввод с адреса

хххх:0100 MOV CX,[10D] ;Прочитать в СХ значение из DS:10D хххх:0104 ADD CX,1A ;Прибавить к содержимому СХ

хххх:0107 MOV [10D],СХ ;Поместить содержимое СХ в DS:10D хххх:010В JMP 100 ;Вернуться к началу программы xxxx:010D DW 2500 ;Определение элемента данных по

С учетом размера PSP DEBUG устанавливает IP равным 100Н, и инструкции программы начинаются с этого адреса. Последнее нажатие (два подряд) указывает DEBUG, что ввод программы завершен. Теперь можно при необходимости использовать команды U (Unassemble) для просмотра машинного кода или Т (Trace) для наблюдения за выполнением программы.

Можно заменять любые введенные команды или элементы данных, при условии, что новые инструкции или элементы будут иметь ту же длину. Например, чтобы заменить инструкцию ADD, расположенную по адресу 104Н, на SUB, введите

хххх:0104 SUB CX,1A

При повторном исполнении программы значение в IP будет продолжать увеличиваться. Для занесения в IP значения 100Н используйте команду R (Register). Для выхода используйте команду Q.

С (Compare)

Сравнивает содержимое двух областей памяти. По умолчанию используется регистр DS. В команде можно указывать длину сравниваемых участков или диапазон адресов:

Пример команды, сравнивающей 20Н байтов, начиная с адреса DS:050, с байтами, начинающимися с DS:200:

С 050 L20 200 ;Сравниваем 20Н байт

Пример команды, сравнивающей байты от DS:050H до DS:070H с байтами, начиная с DS:200:

С 050 070 200 ;Сравниваем диапазоны

Операция выводит на дисплей адреса и содержимое несовпадающих байтов.

D (Display или Dump)

Выводит на экран содержимое области памяти в шестнадцатеричной и ASCII-формах. Регистр по умолчанию – DS. Эту команду также можно использовать, указывая длину или диапазон:

1. d [ [L ]]. Можно указывать начальный адрес с необязательной длиной. Длина по умолчанию – 80Н (128) байт. Вот несколько примеров:

D 200 ;Вывести 80Н байт, начиная с адреса DS:200H

D ;Вывести 80Н байт, начиная с адреса конца

;поcледней выведенной области

D CS:150 ;Вывести 80Н байт, начиная с адреса CS:150H

D DS:20 L5 ;Вывести 5 байт, начиная с адреса DS:20H

2. D [началъный_адрес конечный_адрес] .

D 300 32С ;Вывести байты, начиная с 300Н, и заканчивая 32СН

Е (Enter)

Позволяет вводить в память данные или инструкции машинного кода. Регистр по умолчанию – DS, формат команды – е [ ]. Команда предоставляет две возможности:

1. Заменять байты на указанные в списке, как показано ниже:

Е 105 13 ЗА 21 ;Ввести три байта, начиная с адреса DS:105H

Е CS:211 21 2А ;Ввести два байта, начиная с адреса CS:211H

Е 110 `anything` ;Ввести строку символов, начиная с адреса DS:110H

Использовать для ограничения строк можно как одинарные, так и двойные кавычки.

2. Последовательно редактировать байты. Введите адрес, где расположен байт, который вы хотите просмотреть:

Е 12С ;Просмотреть содержимое байта DS:12CH

Операция будет ожидать ввода с клавиатуры. Введите один или несколько байтов в шестнадцатеричной форме, разделяя их пробелами, начиная с DS:12CH.


F(Fill)

Заполняет область памяти значениями из списка. Регистр по умолчанию -DS. Команду можно использовать как с длиной, так и с диапазоном:

F 210 L19 `Help!` ;Используем длину 19Н (25) байт

F 210 229 ‘Help!’ ;Используем диапазон от 210Н до 229Н

Обе команды заполняют ячейки памяти, начиная с адреса DS:210H байтами, содержащими повторения строки “Help!”.

G (Go)

Выполняет отлаженную программу на машинном языке, вплоть до указанной точки останова (breakpoint). Обязательно убедитесь, что IР содержит корректный адрес для исследуемого участка кода (некорректный адрес может привести к непредсказуемым результатам). Кроме того, устанавливайте точки останова только в своих программах, а не в модулях программ операционной системы или BIOS. Программа будет при необходимости вызывать требуемые обработчики прерываний и останавливаться в ожидании, например, ввода с клавиатуры. Регистр по умолчанию – CS. Формат команды:

Начальный адрес указывать необязательно. Можно указывать до десяти точек останова. Команда G 11А требует выполнить программу, начиная с адреса, заданного в IР, и заканчивая адресом 11АН.

H (Hexadecimal)

Вычисляет сумму и разность двух шестнадцатеричных величин, указанных как н . Например, команда Н 14F 22 выведет в качестве результата 171 (сумму) и 12D (разность).

I (Input)

Считывает и выводит на дисплей один байт из порта. Формат команды

L(Load)

Загружает файл или данные из секторов диска в память. Файл можно указать одним из двух способов: указав имя файла в качестве аргумента при запуске DEBUG, или из запущенного DEBUG командой N (Name). Существует два формата команды L.

1. Загрузка уже указанного файла: l [ ]. Параметр адрес указывает, по какому адресу загрузить в память файл. Если адрес не указан, файл загружается, начиная с адреса CS:100H. Чтобы загрузить файл, не указанный при запуске DEBUG, его необходимо предварительно указать (смотрите команду N):

L ;Загрузить указанный файл, начиная с адреса CS:100H

Чтобы повторно загрузить файл, просто задайте команду L вновь, не указывая адреса. DEBUG вновь считает файл с диска и соответственно проинициализирует регистры.

2. Загрузка данных из секторов диска:

Адрес указывает адрес в памяти, начиная с которого будут размещаться прочитанные данные (по умолчанию это адрес CS: 100).

Диск указывает номер диска (0 – А, 1 – В и т.д.).

Начало указывает шестнадцатеричный номер первого сектора, который нужно прочитать (относительному сектору 0 соответствует цилиндр 1, дорожка 0,сектор 1).

Количество — это шестнадцатеричное число, указывающее, сколько следующих друг за другом секторов нужно прочитать.

Приведенный ниже пример загружает в память, начиная с адреса CS:100, 15Н секторов, начиная с сектора 20Н, с диска А:

Команда L возвращает в пару регистров ВХ:СХ число прочитанных байтов. Для файла типа .EXE DEBUG игнорирует любой указанный адрес и использует адрес загрузки из ЕХЕ-заголовка. Он также стирает из памяти заголовок; чтобы сохранить его, перед вызовом DEBUG переименуйте файл, присвоив ему другое расширение.

М (Move)

Перемещает (точнее, копирует) содержимое ячеек памяти. По умолчанию используется регистр DS. Команду можно использовать, указывая длину или диапазон.

М DS:50 L100 DS:400 ;Перемещаем фрагмент длиной 100Н байтов

М DS:50 150 DS:400 ;Перемещаем байты с DS:50H no DS:150H

Обе команды выполняют одни и те же действия – перемещают байты с адресами от DS:050H до DS:150H по адресу DS:400H.

N (Name)

Задает имя программы или файла, которые нужно прочитать с диска или записать на диск. Команда используется как n , например

Операция сохраняет введенное имя по адресу CS:80H в PSP. Первый байт (по адресу CS:80H) содержит длину (0АН), за ним следует пробел и имя файла. Для чтения файла используется команда L (Load), для записи – W (Write).

О (Output)

Посылает байт в порт, указанный в команде в виде о .

Р (Proceed)

Выполняет инструкцию CALL, LOOP, INT или повторяемую строковую инструкцию (с префиксами REPnn), переходя к следующей инструкции. Формат команды P [= ], где = адрес –- необязательный адрес начала, а значение – необязательное количество инструкций, которые нужно выполнить. Если адрес не указывается, используется текущий адрес из пары CS:IP, а если не указано значение, выполняется одна инструкция. Например, если нужно выполнить обработчик прерывания INT 10H, введите Р, и он выполнится вплоть до следующей инструкции в вашей программе. Смотрите также команды G и Т.

Q(Quit)

Завершает сеанс работы DEBUG. Операция не сохраняет файлы; для этого необходимо применять команду W.

R (Register)

Выводит на дисплей содержимое регистров и следующую инструкцию. Формат команды r [ ]. Вот примеры ее использования.

R Вывести значения из всех регистров.

R DX Вывести значение DX; DEBUG предоставит вам возможность нажать , чтобы оставить содержимое регистра неизменным, или ввести от одной до четырех шестнадцатеричных цифр,которые будут записаны в DX.

R IP Вывести значение IP; можно ввести другое значение с клавиатуры.

R F Вывести состояние флагов; в начале этого приложения приведена таблица, содержащая расшифровку сокращений.

S (Search)

Ищет в памяти символы из списка. Если символы найдены, будет выведен их адрес, если нет — операция не выдаст никакого результата. По умолчанию используется регистр DS. Команду можно использовать, указывая длину или диапазон:

S 300 L2000 ‘VIRUS’

Эта команда будет искать строку «VIRUS» в 2000Н байтах, начиная с адреса DS:300H.

Эта команда ищет символ с ASCII-кодом 51Н в байтах от CS:100Hдо CS:400H.

Т (Trace)

Пошагово выполняет программу. Для выполнения обработчиков прерываний INT лучше пользоваться командой Р (Proceed). По умолчанию используется пара регистров CS:IP. Формат команды T [= ][ ]. Необязательный операнд =adpec указывает DEBUG, откуда начинать пошаговое выполнение, а значение – количество команд, которые необходимо выполнить. Если операнды отсутствуют, DEBUG выполняет одну инструкцию и выводит на дисплей значения из регистров. Вот два примера использования этой команды:

Т ;Выполнить одну следующую инструкцию

Т 10 ;Выполнить следующие 10Н (16) инструкций

Команда Т будет пытаться выполнить что угодно, и если по указанному адресу будет находиться непригодный к исполнению код, процессор может войти в состояние останова, после чего придется перезагружать компьютер.

U (Unassemble)

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

Указанная область памяти должна содержать корректный машинный код, и команда отобразит его в виде символьных инструкций. Вот три примера:

U 100 ;Дизассемблировать 32 байта, начиная с адреса CS:100

U ;Дизассемблировать 32 байта, начиная с адреса, на

;котором закончилась последняя команда U, если она была

U 100 140 ;Дизассемблировать команды из адресов от СS:100 до CS:140

DEBUG некорректно дизассемблирует некоторые инструкции условных переходов и инструкции, специфичные для процессоров 80286 и последующих, но они все равно выполняются корректно, хотя DEBUG и представляет их как выражения DB.

W (Write)

Записывает файл из DEBUG. Необходимо заранее задать имя файла (командой N), если он не был загружен. По умолчанию используется регистр CS. Формат команды

Программы можно записывать только в виде файлов .СОМ. Чтобы изменить программу типа .ЕХЕ, необходимо временно изменить ее расширение. Записывать файлы из DEBUG можно в двух случаях.

1. Прочитав с диска существующую программу, необходимо изменить ее, а затем сохранить. Для этого выполните следующие действия.

• Загрузите программу на машинном языке в память под ее именем: DEBUG .

• С помощью команд D просмотрите программу, и с помощью команд Е внесите изменения.

• Командой W запишите на диск измененную программу.

2. С помощью DEBUG можно написать маленькую программу в машинных кодах и затем сохранить. Для этого необходимо следующее.

• Используя команды A (Assemble) и Е, введите требуемые инструкции.

• Введите имя программы командой N . Расширение файла обязательно должно быть .СОМ.

• Поскольку только вам известна длина всей программы, введите длину в байтах в пару регистров ВХ:СХ.

Рассмотрим такой пример:

хххх:0100 MOV CL,42

хххх:0102 MOV DL,2A

хххх:0104 ADD CL,DL

хххх:0106 JMP 100

Хотя вводятся символьные инструкции, DEBUG преобразует их в машинный код, и именно машинный код будет записан в файл. Поскольку длина последней инструкции, JMP 100, составляет два байта, размер программы равен 8 байтам (от 100Н до 107Н включительно).

• С помощью команды R ВХ просмотрите значение в ВХ и введите 0, чтобы очистить его.

• Командой R СХ просмотрите содержимое СХ. DEBUG выведет значение СХ на дисплей и запросит новое. Введите размер программы, 8.

• Введите команду W , чтобы записать программу на диск.

DEBUG выведет сообщение «Writing 8 bytes.» Если указано число 0, возможно, вы некорректно ввели длину программы – попытайтесь еще раз. Внимательно определяйте размер программы, поскольку значение должно быть шестнадцатеричным, и последняя инструкция может быть длиннее одного байта. Размер программы можно определить, вычтя 100Н из смещения, показанного DEBUG после ввода последней команды программы и нажатия . Например, в рассматриваемом примере после инструкции JMP 100 DEBUG выведет адрес хххх:0108. Значит, размер программы равен 108Н — 100Н = 8 байт.

Дата добавления: 2020-04-04 ; просмотров: 139 ; ЗАКАЗАТЬ РАБОТУ

Dos fn 01h: ввод с клавиатуры

5.4.4. Специальные клавиши DOS


DOS использует некоторые клавиши и комбинации клавиш для реализации определенных функций. Это достигается путем анализа кодов, записываемых в буфер клавиатуры, и выполнения той или иной последовательности действий в зависимости от кода. Реакция на ряд клавиш и их комбинаций определена в драйвере клавиатуры, и никакие коды при их нажатии в буфер клавиатуры не заносятся (об этом мы уже говорили).

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

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

Специальные клавиши делятся на две группы:

1) общие специальные клавиши;

2) специальные клавиши редактирования командной строки.

К общим (управляющим) специальным клавишам относятся следующие :

1. Ctrl — Alt — Del — вызывает рестарт (перезагрузку) DOS без тестирования оборудования ПЭВМ. Ее желательно вводить только в ответ на приглашение DOS ;

2. Pause — приводит к приостановке выполнения программы, в частности, вывода информации на экран дисплея, до нажатия произвольной клавиши. Для достижения этого же эффекта можно использовать комбинации клавиш Ctrl — Num Lock или Ctrl — S , но последняя действует не всегда;

3. Ctrl — Break — обеспечивает принудительное завершение выполнения программы или команды DOS . На 83- и 84-клавишных клавиатурах следует использовать Ctrl — Scroll Lock , а на 101-клавишной — Ctrl — Pause . В большинстве случаев на любой клавиатуре срабатывает и Ctrl — C ;

4. Shift — PrtSc — посылает информацию, изображенную на экране дисплея, на принтер для печати. На 101-клавишной клавиатуре клавишу Shift задействовать не обязательно;

5. Ctrl — PrtSc — включает/выключает дублирование содержимого экрана на принтере (используется для получения твердой копии протокола диалога: при включении дублирования вся выводимая на экран информация будет одновременно печататься на принтере). Можно использовать Ctrl — P ;

6. Ctrl — Alt — Fl — переключает клавиатуру на американский регистр;

7. Ctrl — Alt — F 2 — переключает клавиатуру на национальный регистр;

8. F 6 — вводит символ SUB (маркер конца текстового файла) для завершения набора файла на клавиатуре. Мы не говорили об этом раньше, так как клавиша F 6 некоторыми программными продуктами перепрограммируется, а в DOS используется именно для достижения указанной цели.

Переключение клавиатуры на американский или национальный регистр поддерживается сред­ствами DOS после выполнения команды KEYB .

К специальным клавишам редактирования командной строки относятся следующие:

1. Esc — аннулирует текущую (вводимую) командную строку, но набранная ее часть остается в буфере командной строки. Взамен можно использовать Ctrl -[;

2. BS — удаляет из командной строки последний введенный символ. Можно использовать Ctrl — H ;

3. Enter — завершает ввод командной строки;

4. Ctrl — Enter — осуществляет перевод курсора в начало следующей строки экрана для продолжения набора длинной командной строки. Можно использовать Ctrl — J .

Dos fn 01h: ввод с клавиатуры

Как и в случае вывода на экран, DOS предоставляет набор функций для чтения данных с клавиатуры, которые используют стандартное устройство ввода STDIN, так что можно использовать в качестве источника данных файл или стандартный вывод другой программы.

Функция DOS 0Ah — Считать строку символов из STDIN в буфер

Ввод: АН = 0Ah
DS:DX = адрес буфера
Вывод: Буфер содержит введенную строку

Для вызова этой функции надо подготовить буфер, первый байт которого содержит максимальное число символов для ввода (1 – 254), а содержимое, если оно задано, может использоваться как подсказка для ввода. При наборе строки обрабатываются клавиши Esc, F3, F5, BS, Ctrl-C/Ctrl-Break и т.д., как при наборе команд DOS (то есть Esc начинает ввод сначала, F3 восстанавливает подсказку для ввода, F5 запоминает текущую строку как подсказку, Backspace стирает предыдущий символ). После нажатия клавиши Enter строка (включая последний символ CR (0Dh)) записывается в буфер, начиная с третьего байта. Во второй байт записывается длина реально введенной строки без учета последнего CR.

Рассмотрим пример программы, выполняющей преобразование десятичного числа в шестнадцатеричное.

Функция 0Ah предоставляет удобный, но ограниченный способ ввода данных. Чаще всего используют функции посимвольного ввода, позволяющие контролировать отображение символов на экране, реакцию программы на функциональные и управляющие клавиши и т.д.

Функция 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 = код символа

Кроме перечисленных функций могут потребоваться и некоторые служебные функции 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 очищает буфер клавиатуры, так что следующая функция чтения символа будет ждать ввода с клавиатуры, а не использовать нажатый ранее и еще не обработанный символ. Например, именно эта функция используется для считывания ответа на вопрос «Уверен ли пользователь в том, что он хочет отформатировать диск?».

Функции посимвольного ввода без эха можно использовать для интерактивного управления программой, как в следующем примере.

В этом примере для вывода на экран используется прямое копирование в видеопамять, так как вызов функции BIOS вывода строки (INT 10h, АН = 13h) прокручивает экран вверх на одну строку при выводе символа в нижнем правом углу экрана.

Функции ввода/вывода DOS.

Дата добавления: 2014-11-27 ; просмотров: 833 ; Нарушение авторских прав

Все функции 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=код ошибки.

Илон Маск рекомендует:  Фрэймы и окна. Java Script
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL