INT 16h
INT 16h — это программное прерывание (interrupt) в архитектуре x86, используемое в операционных системах MS-DOS и совместимых с ними для обеспечения доступа к клавиатуре. Оно предоставляет набор функций для чтения нажатий клавиш, проверки состояния буфера клавиатуры и получения информации о состоянии клавиш-модификаторов (Shift, Ctrl, Alt). Прерывание является частью BIOS (Basic Input/Output System) и служит низкоуровневым интерфейсом между прикладным программным обеспечением и аппаратным обеспечением клавиатуры.
История и происхождение
Прерывание INT 16h было введено в первых версиях BIOS для IBM PC (1981 год) и оставалось стандартом для всех совместимых компьютеров в эпоху DOS. Разработка прерывания была обусловлена необходимостью унифицированного доступа к клавиатуре, которая в ранних моделях подключалась через разъём DIN-5 и использовала последовательный протокол. До появления INT 16h программистам приходилось напрямую работать с портами ввода-вывода клавиатуры (60h и 64h), что было сложно и несовместимо между разными производителями.
С развитием операционных систем, таких как Windows и Linux, роль INT 16h снизилась, так как они стали использовать собственные драйверы клавиатуры, работающие через защищённый режим процессора. Однако в утилитах, загрузчиках и эмуляторах DOS (например, DOSBox) прерывание по-прежнему активно используется.
Архитектура и механизм работы
INT 16h реализовано в BIOS как набор подфункций, вызываемых через регистр AH (старший байт регистра AX). Каждая подфункция выполняет определённую операцию с клавиатурой. Основные подфункции:
- AH=00h — чтение следующего символа из буфера клавиатуры. Если буфер пуст, функция блокирует выполнение программы до появления нажатия. Возвращает скан-код (в AH) и ASCII-код (в AL) нажатой клавиши.
- AH=01h — проверка состояния буфера клавиатуры. Возвращает флаг ZF (Zero Flag): если ZF=0, буфер не пуст, и в AX находится скан-код и ASCII-код следующего символа (без удаления из буфера). Если ZF=1, буфер пуст.
- AH=02h — получение состояния клавиш-модификаторов (Shift, Ctrl, Alt, Caps Lock, Num Lock, Scroll Lock). Результат возвращается в регистре AL в виде битовой маски.
- AH=10h — расширенная версия функции 00h для клавиатур, поддерживающих расширенные скан-коды (например, клавиши F11, F12, мультимедийные кнопки).
- AH=11h — расширенная версия функции 01h.
- AH=12h — расширенная версия функции 02h.
Буфер клавиатуры
Клавиатурный буфер — это область памяти (обычно 16 байт), в которую BIOS помещает нажатия клавиш до их обработки программой. Буфер организован как кольцевой массив, что позволяет хранить до 15 нажатий (один байт резервируется для указателя). При переполнении буфера новые нажатия игнорируются, а система издаёт звуковой сигнал (beep). Размер буфера может варьироваться в зависимости от реализации BIOS, но стандартным считается 16 байт.
Скан-коды и ASCII-коды
Каждое нажатие клавиши генерирует скан-код — уникальный номер, соответствующий физическому положению клавиши на клавиатуре. Например, клавиша «A» имеет скан-код 1Eh (в шестнадцатеричной системе). ASCII-код — это символ, который отображается на экране (например, «A» имеет ASCII-код 41h). Для большинства клавиш скан-код и ASCII-код совпадают, но для функциональных клавиш (F1–F12), клавиш управления (Home, End, Arrow) и комбинаций с модификаторами ASCII-код равен 0, а скан-код содержит расширенную информацию.
Классификация подфункций
Подфункции INT 16h можно разделить на три основные категории:
1. Основные функции ввода
- 00h — блокирующее чтение (ожидание нажатия).
- 01h — неблокирующая проверка буфера.
- 10h — расширенное блокирующее чтение (для клавиатур с расширенными скан-кодами).
- 11h — расширенная неблокирующая проверка.
2. Функции состояния модификаторов
- 02h — получение состояния клавиш-модификаторов (Shift, Ctrl, Alt, Caps Lock, Num Lock, Scroll Lock).
- 12h — расширенная версия, возвращающая состояние дополнительных модификаторов (например, правый Alt, правый Ctrl).
3. Устаревшие и редко используемые функции
- 03h — установка скорости автоповтора (repeat rate) и задержки (delay). Эта функция редко поддерживается в современных BIOS.
- 05h — запись скан-кода в буфер клавиатуры (эмуляция нажатия).
- 20h — получение информации о типе клавиатуры (XT, AT, расширенная).
Применение
INT 16h широко использовалось в программах, написанных для MS-DOS, особенно в:
- Играх — для обработки ввода с клавиатуры в реальном времени. Например, в играх 1980-х годов (Doom, Wolfenstein 3D) использовались функции 00h и 01h для опроса клавиатуры.
- Текстовых редакторах — для чтения символов и комбинаций клавиш (Ctrl+C, Ctrl+V). Редакторы, такие как Norton Commander и Far Manager, полагались на INT 16h.
- Утилитах и драйверах — для перехвата нажатий клавиш (например, программы-кейлоггеры или демонстрационные утилиты).
- Загрузчиках операционных систем — для выбора режима загрузки (например, GRUB в текстовом режиме).
В современных системах INT 16h используется в основном в эмуляторах DOS (DOSBox, QEMU, VirtualBox) и встроенных системах, где требуется совместимость с устаревшим программным обеспечением.
Примеры использования
Пример 1: Чтение символа с клавиатуры (ассемблер x86)
``assembly mov ah, 00h ; функция чтения символа int 16h ; вызов прерывания ; теперь AL содержит ASCII-код, AH — скан-код ``
Пример 2: Проверка буфера без блокировки
``assembly mov ah, 01h ; функция проверки буфера int 16h jz no_key ; если ZF=1, буфер пуст ; если ZF=0, в AX — скан-код и ASCII-код no_key: ``
Пример 3: Получение состояния модификаторов
``assembly mov ah, 02h ; функция состояния модификаторов int 16h ; AL содержит битовую маску: ; бит 0 — правый Shift ; бит 1 — левый Shift ; бит 2 — Ctrl ; бит 3 — Alt ; бит 4 — Scroll Lock ; бит 5 — Num Lock ; бит 6 — Caps Lock ; бит 7 — Insert ``
Критика и ограничения
INT 16h имеет несколько недостатков, которые ограничивают его применение в современных системах:
- Зависимость от реального режима процессора. Прерывание работает только в реальном режиме (16-бит), который используется в DOS. В защищённом режиме (32-бит) и длинном режиме (64-бит) вызов INT 16h приводит к ошибке, если не настроен специальный обработчик.
- Ограниченный буфер. Размер буфера в 16 байт может быть недостаточным для быстрого набора текста или игр с высокой частотой ввода. При переполнении буфера нажатия теряются.
- Отсутствие поддержки мультимедийных клавиш. Стандартное INT 16h не поддерживает клавиши регулировки громкости, вызова браузера и т.д. Расширенные функции (10h, 11h) частично решают эту проблему, но не для всех клавиатур.
- Несовместимость с USB-клавиатурами. В старых BIOS, не поддерживающих USB Legacy Mode, INT 16h не работает с USB-клавиатурами. В современных системах эта проблема решена эмуляцией PS/2-клавиатуры.
Интересные факты
- В некоторых реализациях BIOS функция 00h INT 16h может быть переопределена для поддержки раскладок клавиатуры, отличных от QWERTY (например, ЙЦУКЕН). Это достигается путём модификации таблицы перекодировки скан-кодов в ASCII-коды.
- Прерывание INT 16h является частью более широкого набора прерываний BIOS, включающего INT 10h (видео), INT 13h (диск) и INT 21h (DOS). Вместе они образуют основу для разработки программ под MS-DOS.
- В эмуляторе DOSBox INT 16h эмулируется через хост-систему, что позволяет использовать современные клавиатуры и раскладки без потери функциональности.
Источники
- IBM PC/AT Technical Reference Manual, 1984.
- Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3: System Programming Guide.
- Ralf Brown’s Interrupt List (RBIL) — документация по прерываниям BIOS и DOS.
- «The Art of Assembly Language» by Randall Hyde, 2003.
- MS-DOS Encyclopedia, Microsoft Press, 1988.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →