Механизм и типы прерываний.
1.1. Механизм и типы прерываний.
Для обработки событий, происходящих асинхронно по отношению к
выполнению программы, лучше всего подходит механизм прерываний.
Прерывание можно рассматривать как некоторое особое событие в сис-
теме, требующее моментальной реакции. Например, хорошо спроектиро-
ванные системы повышенной надежности используют прерывание по ава-
рии в питающей сети для выполнения процедур записи содержимого
регистров и оперативной памяти на магнитный носитель, с тем чтобы
после восстановления питания можно было бы продолжить работу с то-
го же места.
Поскольку прерывания возможны самые разнообразные по самым
различным причинам, каждому прерыванию присваивается номер преры-
вания. С каждым номером прерывания связывается то или иное собы-
тие. Система умеет разпознать какое прерывание, с каким номером
произошло, и запускает соответствующую этому номеру процедуру.
По источнику и характеру возникновения прерывания можно раз-
делить на группы (рис. 1):
Прерывания
+-------------------------+
Аппаратные Программные
+--------------------+
Внешние Внутренние
+--------------+
Маскируемые Немаскируемые
Рис. 1.
Программные прерывания вызывают сами программы, поэтому они не
являются асинхронными. Для этого они используют команду INT.
Программные прерывания удобно использовать для организации
доступа к отдельным общим для всех программ модулям. Например,
программные модули операционной системы доступны прикладным прог-
раммам именно через прерывания, и нет необходимости при вызове
этих модулей знать их текущий адрес в памяти. Прикладные программы
сами могут устанавливать свои обработчики прерываний для их после-
дующего использования другими программами. Для этого встраиваемые
обработчики прерываний должны быть резидентными в памяти.
Аппаратные прерывания вызываются физическиими устройствами и
приходят асинхронно. Эти прерывания информируют систему о событи-
ях, связанных с работой устройств, например о том, что завершилась
печать символа на принтере и неплохо было бы выдать следующий сим-
вол, или о том, что требуемый сектор диска уже прочитан, его со-
держание доступно программе.
Использование прерываний при работе с медленными внешними ус-
тройствами позволяет совместить ввод/вывод с обработкой данных в
центральном процессоре и в результате повышает общую производи-
тельность системы.
Внешние аппаратные прерывания вызваны сигналами, внешними по
отношению к цетрральному процессору, и подаются на его входы INT и
NMI.
Прерывания по входу INT относятся в аппаратным маскируемым
прерываниям, поскольку могут быть разрешены или запрещены флагом
IF регистра флагов. Номер вектора прерываний маскируемых прерыва-
ний передается в процессор по его восьми младшим разрядам шины
данных.
Вход немаскируемого прерывания NMI обычно используется для
сообщений о "катастрофических" событий (отключении питания, обна-
ружении ошибок памяти и т.д.). Номер этого прерывания равен 2.
Внутренние (логические) прерывания формируются самим процес-
сором, когда он встречается с некоторыми особыми событиями вроде
деления на 0. Это прерывания с номерами 0, 1, 3, 4 (см. табл.1).
В таблице 1 дано описание наиболее важных прерываний.
Таблица 1
+----------------------------------------------------------------+
¦ Номер ¦ Описание ¦
+----------------------------------------------------------------+
0 Ошибка деления. Вызывается автоматически после
выполнения команд DIV или IDIV, если в результате
деления произошло переполнение. DOS обычно при об
работке этого прерывания выводит сообщение об ошиб-
ке и остановливает выполнение программы. Для процес-
сора 8086 при этом адрес возврата указывает на сле-
дующую после команды деления команду, а в процессоре
80286 - на первый байт команды, вызвавшей прерывание
1 Прерывание пошагового режима. Вырабатывается после
выполнения каждой машинной команды, если в слове
флагов установлен бит пошаговой трассировки TF.
Используется для отладки программ. Прерывание не вы-
рабатывается после выполнения команды MOV в сегмент-
ные регистры или после загрузки сегментных регистров
командой POP
2 Аппаратное немаскируемое прерывание. Это прерывание
может использоваться по-разному в разных машинах.
Обычно вырабатывается при ошибке четности в опера-
тивной памяти и при запросе прерываний от сопроцес-
сора
3 Прерывание для трассировки. Это прерывание генериру-
ется при выполнении однобайтовой команды с кодом CCh
и обычно используется отладчиками для установки точки
прерывания
4 Переполнение. Генерируется машинной командой INTO,
если установлен флаг OF. Если флаг не установлен, то
команда INTO выполняется как NOP. Это прерывание ис-
пользуется для обработки ошибок при выполнении ариф-
метических операций
5 Печать копии экрана. Генерыруется при нажатии на кла-
виатуре клавиши PrtScr. Обычно используется для печати
образа экрана. Для процессора 80286 генерируется при
выполнении машинной команды BOUND, если проверяемое
значение вышло за пределы заданного диапазона
6 Неопределенный код операции или длина команды больше
10 байтов (для процессора 80286)
7 Особый случай отсутствия сопроцессора
8 IRQ0 - прерывание интервального таймера, возникает 18,2
раза в секунду
9 IRQ1 - прерывание от клавиатуры. Генерируется при нажа-
тии и при отжатии клавиши. Используется для чтения дан-
ных от клавиатуры
A IRQ2 - используется для каскадирования аппаратных пре-
рываний в машинах класса AT
B IRQ3 - прерывание асинхронного порта COM2
C IRQ4 - прерывание асинхронного порта COM1
D IRQ5 - прерывание от контроллера жесткого диска для XT
E IRQ6 - прерывание генерируется контроллером флоппи-дис-
ка после завершения операции
F IRQ7 - прерывание принтера. Генерируется принтером,
когда он готов к выполнению очередной операции. Многие
адаптеры принтера не используют это прерывание
10 Обслуживание видеоадаптера
11 Определение конфигурации устройств в системе
12 Определение размера оперативной памяти в системе
13 Обслуживание дисковой системы
14 Последовательный ввод/вывод
15 Расширенный сервис для AT-компьютеров
16 Обслуживание клавиатуры
17 Обслуживание принтера
18 Запуск BASIC в ПЗУ, если он есть
19 Загрузка операционной системы
1A Обслуживание часов
1B Обработчик прерываний Ctrl-Break
1C Прерывание возникает 18,2 раза в секунду, вызывается
программно обработчиком прерывания таймера
1D Адрес видеотаблицы для контроллера видеоадаптера 6845
1E Указатель на таблицу параметров дискеты
1F Указатель на графическую таблицу для символов с кодами
ASCII 128-255
20-5F Используются DOS или зарезервированы для DOS
60-67 Прерывания, зарезервированные для пользователя
68-6F Не используются
70 IRQ8 - прерывание от часов реального времени
71 IRQ9 - прерывание от контроллера EGA
72 IRQ10 - зарезервировано
73 IRQ11 - зарезервировано
74 IRQ12 - зарезервировано
75 IRQ13 - прерывание от сопроцессора
76 IRQ14 - прерывание от контроллера жесткого диска
77 IRQ15 - зарезервировано
78-7F Не используются
80-85 Зарезервированы для BASIC
86-F0 Используются интерпретатором BASIC
F1-FF Не используются
-------------------------------------------------------------
1.2. Таблица векторов прерываний.
Для того чтобы связать номер прерывания с адресом программы
обработки прерываний (обработчика прерываний), используется табли-
ца векторов прерываний, занимающая первый килобайт оперативной па-
мяти - адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256
элементов - FAR-адресов обработчиков прерываний. Эти элементы на-
зываются векторами прерываний. В первом слове элемента таблицы за-
писано смещение, а во втором - сегмент адреса обработчика прерыва-
ний.
Прерыванию с номером 0 соответствует адрес 0000:0000,
прерыванию с номером 1 - 0000:0004 и т.д. Прерыванию с номером n
будет соответствовать адрес 0000:4*n.
Инициализация таблицы происходит частично программой BIOS
после тестирования аппаратуры, частично при загрузке DOS. DOS мо-
жет переключить на себя некоторые прерывания BIOS.
1.3. Обработка прерываний.
Несмотря на многообразие типов прерываний алгоритм обработки
прерывания процессором один и тот же и изображен на рис.2.
+
--1-------- ¦ N - номер вектора
Начало - - - ¦ прерывания
----------- +
+ +
¦ +--2----------+ ¦ поместить в стек
¦ ¦ ¦- - - ¦ регистр флагов
¦ +-------------+ +
¦ +
¦ +--3----------+ ¦ обнулить флаги
¦ ¦ ¦- - - ¦ IF и TF
¦ +-------------+ +
¦ +
¦ +--4----------+ ¦ поместить в стек
¦ ¦ ¦- - - ¦ значение регистра CS
¦ +-------------+ +
команда ¦ + присвоить адресу
Int ¦ +--5----------+ ¦ вектора прерывания
(interrupt) < ¦ ¦- - - ¦ значение N*4
¦ +-------------+ +
¦ + загрузить второе слово
¦ +--6----------+ ¦ вектора прерываний
¦ ¦ ¦- - - ¦ в регистр CS
¦ +-------------+ +
¦ +
¦ +--7----------+ ¦ поместить в стек
¦ ¦ ¦- - - ¦ значение IP
¦ +-------------+ +
¦ + загрузить первое слово
¦ +--8----------+ ¦ вектора прерываний
¦ ¦ ¦- - - ¦ в указатель команд IP
¦ +-------------+ +
+
+ выполнить действия
+--9----------+ ¦ по обслуживанию
¦ ¦- - - ¦ данного прерывания
+-------------+ +
+ + извлечь из стека значение
¦ +--10---------+ ¦ и загрузить в
¦ ¦ ¦- - - ¦ указатель команд IP
¦ +-------------+ +
¦ + извлечь из стека значение
команда ¦ +--11---------+ ¦ и загрузить в регистр
Iret < ¦ ¦- - - ¦ сегмента команд CS
(interrupt ¦ +-------------+ +
return) ¦ + извлечь из стека значение
¦ +--12---------+ ¦ и загрузить в
¦ ¦ ¦- - - ¦ регистр флагов
¦ +-------------+ +
+
--13-------
Конец
-----------
Рис. 2.
1.4. Маскирование прерываний.
Часто при выполнении критических участков программ, для того
чтобы гарантировать выполнение определенной последовательности ко-
манд, приходится запрещать прерывания. Это можно сделать командой
CLI (сброс флага разрешения прерывания). Ее нужно поместить в на-
чало критической последовательности команд, а в конце расположить
команду STI (установить флаг разрешения прерывания). Команда CLI
запрещает только маскируемые прерывания, немаскируемые всегда об-
рабатываются процессором.
Если вы используете запрет прерываний с помощью команды CLI,
следите за тем, чтобы прерывания не отключались на длительный пе-
риод времени, т.к. это может привести к нежелательным последстви-
ям, например, будут отставать часы.
Если надо запретить не все прерывания, а только некоторые,
например, от клавиатуры, то для этого надо воспользоваться услуга-
ми контроллера прерываний.
1.5. Изменение таблицы векторов прерываний. Если программе
потребуется организовать обработку некоторых прерываний, то для
этого необходимо переназначить требуемый вектор прерываний на свой
обработчик. Это можно сделать, изменив содержание соответствующего
элемента таблицы векторов прерываний.
Очень важно не забыть перед завершением работы программы восс-
тановить содержимое измененных векторов, т.к. после завершения ра-
боты программы память, которая ей была распределена, считается
свободной и может быть использована для загрузки другой программы.
Если вектор не был восстановлен, и пришло прерывание, то работа
системы может нарушиться - вектор теперь указывает на область, ко-
торая может содержать все, что угодно.
Поэтому последовательность действий для нерезидентных прог-
рамм, обрабатывающих прерывания, должна быть такой:
-прочитать содержимое элемента таблицы векторов прерываний
для вектора с номером того прерывания, какое требуется обработать;
-запомнить это содержимое (адрес старого обработчика прерыва-
ний) в области данных программы;
-установить новый адрес в таблице векторов прерываний так,
чтобы он соответствовал началу программы обработки прерываний
пользователя;
-перед завершением работы программы прочитать из области дан-
ных адрес старого обработчика прерывания и записать его в таблицу
векторов прерываний.
Отметим, что для резидентных программ (т.е. программ постоянно
находящихся в оперативной памяти) последний пункт выполнять не
нужно.
Операция изменения вектора прерываний должна быть непрерывной
в том смысле, что во время изменения не должно произойти прерыва-
ние с номером, для которого производится замена программы обработ-
ки. Если, например, будет записано новое значение смещения, а сег-
мент адреса не успеет обновиться, то по какому адресу будет
передано управления в случае прерывания и что при этом произойдет?
Поэтому перед записью в вектор прерываний нужно запретить пре-
рывания командой CLI, а после записи - разрешить командой STI.
Для облегчения работы по замене прерывания DOS имеет специаль-
ные функции для чтения элемента таблицы прерываний и для записи в
нее нового адреса. Правильность операций при этом будет гарантиро-
вана.
Для чтения вектора используйте функцию 35h DOS (прерывания 21
h). Перед ее вызовом регистр AL должен содержать номер вектора в
таблице. После выполнения функции в регистрах ES:BX будет искомый
адрес обработчика прерывания.
Функция 25h DOS установливает для вектора с номером, находя-
щимся в AL, обработчик прерываний DS:DX.
1.6. Коррекция системных обработчиков прерываний.
Если необходимо добавить какие-либо собственные действия к
тем, что выполняет стандартный обработчик прерывания, то можно ор-
ганизовать цепочку прерываний.
Для организации цепочки прерываний необходимо записать в таб-
лицу векторов адрес собственного обработчика, не забыв сохранить
прежнее содержимое таблицы. Обработчик пользователя получает уп-
равление по прерыванию, выполняет какие-либо действия, затем пере-
дает управление стандартному обработчику. Можно сделать и по-дру-
гому: Обработчик пользователя вызывает стандартный обработчик, а
затем выполняет дополнительные действия. Т.е. можно вставить до-
полнительную обработку как до вызова стандартного обработчика, так
и после его вызова.
1.7. Состояние клавиш-переключателей.
В таблице 2 приведен формат байта по адресу 0040H:0017H, со-
держащий текущие состояния клавиш-переключателей.
Таблица 2
--------------------------------------
Бит Значение, когда бит=1
--------------------------------------
0 нажата клавиша правый Shift
1 нажата клавиша левый Shift
2 нажата клавиша Ctrl
3 нажата клавиша Alt
4 режим ScrollLock включен
5 режим NumLock включен
6 режим CapsLock включен
7 режим вставки включен
---------------------------------------