Векторные прерывания. Организация вложенных прерываний


Здесь мы разберем такие важные темы, как: обработка прерываний, векторы прерываний, программные прерывания, IRQ , в общем поговорим на темы прерывания.

Идея прерывания была предложена в середине 50-х годов и основная цель введения прерываний – реализация синхронного режима работы и реализация параллельной работы отдельных устройств ЭВМ.

Прерывания и обработка прерываний зависят от типа ЭВМ, поэтому их реализацию относят к машинно-зависимым свойствам операционных систем.

Прерывание (interrupt) – это сигнал, заставляющий ЭВМ менять обычный порядок выполнения команд процессором.

Возникновение подобных сигналов обусловлено такими событиями , как:

  • завершение операций ввода-вывода.
  • истечение заранее заданного интервала времени.
  • попытка деления на нуль.
  • сбой в работе аппаратного устройства и др.

Обработка прерывания

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

Например прерывание с номером 9 — прерывание от клавиатуры, которое генерируется при нажатии и при отжатии клавиши. Используется для чтения данных с клавиатуры. Обозначается в ОС как IRQ 1, где IRQ – обозначение прерывания, а 1 – приоритет прерывания. Данные о запросах на прерывание можно проанализировать в диспетчере устройств:

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

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

Векторы прерываний

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

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

Таблица векторов прерываний занимает первый килобайт оперативной памяти — адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов — FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний . В первом слове элемента таблицы записано смещение, а во втором — адрес сегмента обработчика прерывания. Векторами являются просто полные адреса памяти программы (в сегментированной форме), которая должна быть активизирована в случае возникновения прерывания.

Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 — 0000:0004 и т.д. Адрес такой состоит из пары 2-байтовых слов, поэтому каждый из векторов занимает четыре байта.

Можно просмотреть таблицу векторов прерываний в компьютере, если воспользоваться программой DEBUG. Используйте команду D для вывода содержимого начала памяти: D 0:0. Программа DEBUG покажет вам первые 128 байтов или 32 вектора, которые могут иметь вид наподобие следующего:

0000:0000 E8 4E 9A 01 00 00 00 00-C3 E2 00 F0 00 00 00 00
0000:0010 F0 01 70 00 54 FF 00 F0-05 18 00 F0 05 18 00 F0
0000:0020 2C 08 51 17 D0 0A 51 17-AD 08 54 08 E8 05 01 2F
0000:0030 FA 05 01 2F 05 18 00 F0-57 EF 00 F0 F0 01 70 00
0000:0040 90 13 C7 13 4D F8 00 F0-41 F8 00 F0 3E 0A 51 17
0000:0050 5C 00 B7 25 59 F8 00 F0-E2 0A 51 17 9C 00 B7 25
0000:0060 00 00 00 F6 8E 00 DE 09-6E FE 00 F0 F2 00 7B 09
0000:0070 27 08 51 17 A4 F0 00 F0-22 05 00 00 00 00 00 F0

Векторы хранятся как «слова наоборот»: сначала смещение, а потом сегмент. Например, первые четыре байта, которые программа DEBUG показала выше (E8 4E 9A 01) можно преобразовать в сегментированный адрес 019A:4EE8.

Можно встретить три вида адресов в таблице векторов . Это могут быть адреса, указывающие на ROM-BIOS, которые можно идентифицировать шестнадцатеричной цифрой F, которая предшествует номеру сегмента. Это могут быть адреса, которые указывают на главную память (как в примере: 019A:4EE8). Эти адреса могут указывать на подпрограммы ДОС или на резидентную программу (например, SideKick или Prokey), либо они могут указывать на саму программу DEBUG (поскольку DEBUG должна временно управлять прерыванием). Также векторы могут состоять из одних нулей, когда прерывание с данным номером не обрабатывается в текущий момент.

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

Ниже приведено назначение некоторых векторов:

Описание
0 Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0).
2 Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора.
5 Печать копии экрана. Генерируется при нажатии на клавиатуре клавиши PrtScr. Обычно используется для печати образа экрана.
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 Последовательный ввод/вывод.
1A Обслуживание часов.
1B Обработчик прерывания Ctrl-Break.
70 IRQ8 — прерывание от часов реального времени.
71 IRQ9 — прерывание от контроллера EGA.
75 IRQ13 — прерывание от математического сопроцессора.
76 IRQ14 — прерывание от контроллера жесткого диска.
77 IRQ15 — зарезервировано.

IRQ0 — IRQ15 — это аппаратные прерывания.

Механизм обработки прерываний

При обработке каждого прерывания должна выполняться следующая последовательность действий:

  • Восприятие запроса на прерывание: прием сигнала и идентификация прерывания.
  • Запоминание состояния прерванного процесса: определяется значением счетчика команд (адресом следующей команды) и содержимым регистров процессора.
  • Передача управления прерывающей программе (в счетчик команд заносится начальный адрес подпрограммы обработки прерываний, а в соответствующие регистры – информация из слова состояния процессора).
  • Обработка прерывания.
  • Восстановление прерванного процесса и возврат в прерванную программу.

Главные функции механизма прерывания:

  1. распознавание или классификация прерываний.
  2. передача управления соответственно обработчику прерываний.
  3. корректное возвращение к прерванной программе (перед передачей управления обработчику прерываний содержимое регистров процессора запоминается либо в памяти с прямым доступом либо в системном стеке).

Типы прерываний

Прерывания, возникающие при работе вычислительной системы, можно разделить на 4 группы:

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

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

Внешние прерывания возникают по сигналу какого-либо внешнего устройства например:

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

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

Маскируемые и немаскируемые внешние прерывания

Существуют два специальных внешних сигнала среди входных сигналов процессора, при помощи которых можно прервать выполнение текущей программы и тем самым переключить работу центрального процессора. Это сигналы NMI (Non Mascable Interrupt, немаскируемое прерывани ) INTR (interrupt request, запрос на прерывание ).

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

Часто при выполнении критических участков программ, для того чтобы гарантировать выполнение определенной последовательности команд целиком, приходится запрещать прерывания (т.е. сделать систему нечувствительной ко всем или отдельным прерываниям). Это можно сделать командой CLI. Ее нужно поместить в начало критической последовательности команд, а в конце расположить команду STI, разрешающую процессору воспринимать прерывания. Команда CLI запрещает только маскируемые прерывания, немаскируемые всегда обрабатываются процессором.

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

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

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

Программные прерывания

Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. По этой команде процессор осуществляет практически те же действия, что и при обычных прерываниях, но только это происходит в предсказуемой точке программы – там, где программист поместил данную команду. Поэтому программные прерывания не являются асинхронными (программа «знает», когда она вызывает прерывание).

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

Механизм программных прерываний был специально введен для того, чтобы:

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

Пример (программные прерывания):

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

В упрощенном виде схему обработки различных видов прерываний можно представить следующим образом:

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

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

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

В случае о прерывании самой программы обработки прерывания говорят о вложенном прерывании . Уровни приоритетов обозначаются сокращенно IRQ0 — IRQ15 или IRQ0 – IRQ23 (в зависимости от микросхемой реализации).

Пpepывaнию вpeмeни cутoк дан мaкcимaльный пpиopитeт, пocкoльку ecли oнo будет пocтoяннo тepятьcя, то будут нeвepными пoкaзaния cиcтeмныx чacoв. Пpepывaниe от клaвиaтуpы вызывaeтcя при нaжaтии или oтпуcкaнии клавиши; oнo вызывaeт цепь coбытий, кoтopaя oбычнo зaкaнчивaeтcя тем, что код клавиши пoмeщaeтcя в буфep клaвиaтуpы (oткудa он зaтeм мoжeт быть пoлучeн пpoгpaммными пpepывaниями).

Ну и наконец реализация механизма обработки прерываний

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

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

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

Сохранение и восстановление состояния процессора и содержимого регистров называют операцией контекстного переключения .

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

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

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

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

Это поле используется, чтобы не допустить наступления прерываний определенного типа, пока первое из них не будет обработано. В MASK каждый бит соответствует некоторому классу прерываний. Если какой-то бит установлен в 1, то прерывания соответствующего класса разрешены, если в 0, то запрещены. В последнем случае говорят, что они маскированы (их также называют запрещенными или закрытыми ). Однако маскированные прерывания не теряются, потому что сигнал, вызвавший прерывание, сохраняется аппаратурой. Временно задержанное таким способом прерывание называется отложенным . Когда (вследствие того, что значение MASK сброшено) прерывания соответствующего класса вновь разрешаются, сигнал опознается и происходит прерывание.

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

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

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

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

Каждое событие, требующее прерывания, сопровождается сигналом, оповещающим ЭВМ – запросами прерывания. Программу, затребованную запросом прерывания, называют прерывающей программой, противопоставляя ее прерываемой программе, выполнявшейся машиной до появления запроса.

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

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

Основными функциями системы прерывания являются:

    запоминание состояния прерываемой программы и осуществление перехода к прерывающей программе

    восстановление состояния прерванной программы и возврат к ней.

Вектором прерывания называется вектор «начального состояния прерывающей программы». Вектор прерывания содержит всю необходимую информацию для перехода к прерывающей программе, в том числе ее начальный адрес. Каждому запросу (номеру) прерывания соответствует свой вектор прерывания, способный инициировать выполнение соответствующей прерывающей программы. Векторы прерывания находятся в специально выделенных фиксированных ячейках памяти – таблице векторов прерываний.

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

Классификация прерываний

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

Семейство микропроцессоров Intel 80x86 поддерживает 256 уровней приоритетных прерываний, вызываемых событиями трех типов:

    внутренние аппаратные прерывания

    внешние аппаратные прерывания

    программные прерывания

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

Внешние аппаратные прерывания инициируются контроллерами периферийного оборудования или сопроцессорами (например, 8087/80287). Источники сигналов прерываний подключаются либо к выводу немаскируемых прерываний процессора (NMI) либо к выводу маскируемых прерываний (INTR). Линия NMI обычно предназначает для прерываний, вызываемых катастрофическими событиями, такими, как ошибки четности памяти или авария питания.

Программные прерывания . Любая программа может инициировать синхронное программное прерывание путем выполнения команды int . MS-DOS использует для взаимодействия со своими модулями и прикладными программами прерывания от 20Н до 3FH (например, доступ к диспетчеру функций MS-DOS осуществляется выполнением команды i nt 21 h ). Программы BIOS, хранящиеся в ПЗУ, и прикладные программы IBM PC используют другие прерывания, с большими или меньшими номерами. Это распределение номеров прерываний условно и никаким образом не закреплено аппаратно.

Таблица векторов прерываний

Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти. Эта таблица находится в диапазоне адресов от 0000:0000 до 0000:03FFh и состоит из 256 элементов – дальних адресов обработчиков прерываний.

Элементы таблицы векторов прерываний называются векторами прерываний. В первом слове элемента таблицы записана компонента смещения, а во втором – сегментная компонента адреса обработчика прерывания.

Вектор прерывания с номером 0 находится по адресу 0000:0000, с номером 1 - по адресу 0000:0004 и т. д. В общем случае адрес вектора прерывания находится путем умножения номера прерывания на 4.

Инициализация таблицы выполняется частично системой базового ввода/вывода BIOS после тестирования аппаратуры и перед началом загрузки операционной системой, частично при загрузке MS-DOS. Операционная система MS-DOS может изменить некоторые вектора прерываний, установленные BIOS.

Таблица векторов прерываний

Номер

Описание

Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). Обычно при обработке этого прерывания MS-DOS выводит сообщение об ошибке и останавливает выполнение программы. При этом для процессора i8086 адрес возврата указывает на команду, следующую после команды деления, а для процессора i80286 и более поздних моделей - на первый байт команды, вызвавшей прерывание

Прерывание пошагового режима. Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после пересылки данных в сегментные регистры командами MOV и POP

Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно оно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора

Прерывание для трассировки. Генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания

Переполнение. Генерируется машинной командой INTO , если установлен флаг переполнения OF. Если флаг не установлен, команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций

Печать копии экрана. Генерируется, если пользователь нажал клавишу В программах MS-DOS обычно используется для печати образа экрана. Для процессора i80286 и более старших моделей генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона

Неопределенный код операции или длина команды больше 10 байт

Особый случай отсутствия арифметического сопроцессора

IRQ0 – прерывание интервального таймера, возникает 18,2 раза в секунду

IRQ1 – прерывание от клавиатуры. Генерируется, когда пользователь нажимает и отжимает клавиши. Используется для чтения данных из клавиатуры

IRQ2 – используется для каскадирования аппаратных прерываний

IRQ3 – прерывание асинхронного порта COM2

IRQ4 – прерывание асинхронного порта COM1

IRQ5 – прерывание от контроллера жесткого диска (только для компьютеров IBM PC/XT)

IRQ6 – прерывание генерируется контроллером НГМД после завершения операции ввода/вывода

IRQ7 – прерывание от параллельного адаптера. Генерируется, когда подключенный к адаптеру принтер готов к выполнению очередной операции. Обычно не используется

Обслуживание видеоадаптера

Определение конфигурации устройств в системе

Определение размера оперативной памяти

Обслуживание дисковой системы

Работа с асинхронным последовательным адаптером

Расширенный сервис

Обслуживание клавиатуры

Обслуживание принтера

Запуск BASIC в ПЗУ, если он есть

Обслуживание часов

Обработчик прерывания, возникающего, если пользователь нажал комбинацию клавиш

Программное прерывание, вызывается 18,2 раза в секунду обработчиком аппаратного прерывания таймера

Адрес видеотаблицы для контроллера видеоадаптера 6845

Указатель на таблицу параметров дискеты

Указатель на графическую таблицу для символов с кодами ASCII 128-255

Используется MS-DOS или зарезервировано для MS-DOS

Прерывания, зарезервированные для программ пользователя

Не используются

IRQ8 – прерывание от часов реального времени

IRQ9 – прерывание от контроллера EGA

IRQ10 – зарезервировано

IRQ11 – зарезервировано

IRQ12 – зарезервировано

IRQ13 – прерывание от арифметического сопроцессора

IRQ14 – прерывание от контроллера жесткого диска

IRQ15 – зарезервировано

Не используются

Зарезервировано для BASIC

Используются интерпретатором BASIC

Не используются

Прерывания, обозначенные как IRQ0 – IRQ15 являются внешними аппаратными.

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

В общем случае все эти ситуации разделяются по принципу их обнаружения, источника возникновения и реакции на них на следующие три категории:

  • Прерывания и особые ситуации (Interrupts and Exceptions ) — обнаруживаются и обрабатываются процессором в самые различные моменты времени и могут происходить как из внешних так и из внутренних источников, все другие типы экстраординарных ситуаций занимают более низкий уровень иерархии и могут обрабатываться, только если сперва заявят о своем существовании через прерывание или особую ситуацию.
  • Исключительные ситуации FPU (Floating-Point Exceptions команд сопроцессора , команд MMX или 3DNow!-команд . Возникновение исключительной ситуации FPU , в свою очередь, может вызывать генерацию прерывания через подачу сигнала на специальные внешние выводы процессора (так называемая реакция в стиле MS-DOS ) или особой ситуации (внутренний механизм процессора обеспечивает генерацию ошибки сопроцессора #MF), обработчик которой далее сам разбирается с тем, какое исключение произошло и какие действия в связи с этим следует предпринять ().
  • Исключительные ситуации SIMD (SSE) (SIMD Floating-Point Exceptions ) — могут возникать только при выполнении SIMD-команд и полностью определяются состоянием SIMD-регистров процессора. SIMD-исключения сообщают о своем возникновении через генерацию специальной особой ситуации #XM . Получив управление, обработчик особой ситуации должен сам программным путем определить причину возникновения исключения ().

Прерывания и особые ситуации

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

Все прерывания и особые ситуации имеют уникальные идентификационные номера . Эти номера называются векторами прерываний и лежат в пределах от 0 до 255. Векторы от 0 до 31 отведены для особых ситуаций и немаскируемого прерывания , причем некоторые из них зарезервированы и не должны использоваться программами. Векторы от 32 до 255 свободны для любого использования пользовательскими программами и внешними устройствами.

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

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

Любые невыровненные ссылки на данные в памяти, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3)

Типы особых ситуаций и особенности их обработки

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

  • Ошибка (Fault ) — это особая ситуация , которая может быть исправлена обработчиком особой ситуации . При встрече ошибки состояние процессора сохраняется в том виде, каким оно было до начала выполнения команды, инициировавшей генерацию ошибки, а значения CS:EIP , указывающие на эту команду сохраняются в стеке обработчика. Прерванная программа после исправления ошибки может быть продолжена непосредственно с команды, вызвавшей эту ошибку .
  • Ловушка (Trap ) — особая ситуация , которая генерируется после выполнения соответствующей команды. В этом случае сохраняемые в стеке значения CS:EIP , указывают на команду, которая будет выполняться вслед за командой, вызвавшей ловушку ; например, если ловушка произошла во время команды JMP , то сохраненные значения CS:EIP указывают на команду, являвшуюся целью команды JMP .
  • Сбой (Abort ) — это особая ситуация , которая не допускает точную локализацию вызвавшей ее команды и не допускает перезапуска. Сбои используются для сообщений о некоторых ошибках, таких как: технические неисправности и наличие некорректных значений в системных таблицах.

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

  • таблица дескрипторов прерываний IDT (в режиме реальной адресации — таблица векторов прерываний IVT);
  • регистр таблицы дескрипторов прерываний IDTR ;
  • флаг маскирования внешних прерываний EFLAGS.IF ;
  • флаги для работы с виртуальными прерываниями EFLAGS.VIF , EFLAGS.VIP ;
  • специальная таблица — карта перенаправления прерываний IRB — располагается в сегменте TSS задачи;
  • специальные типы дескрипторов шлюзов .

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

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

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

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

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

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


t p – время реакции системы на прерывание;
t з – время запоминания состояния прерываемой программы;
t ппр – время собственно прерывающей программы;
t в – время восстановления состояния прерванной программы

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

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

Характеристиками системы прерывания являются:

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

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

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

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

Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. Это так называемые программные прерывания. Программные прерывания не являются асинхронными, так как вызываются из программы (а она-то знает, когда она вызывает прерывание!).

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

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

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

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

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

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

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

4.2. Таблица векторов прерываний

Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти - адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов - FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором - адрес сегмента обработчика прерывания.

Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 - 0000:0004 и т.д. Для программиста, использующего язык Си, таблицу можно описать следующим образом:

void (* interrupt_table)();

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

Займемся теперь содержимым таблицы векторов прерываний. Приведем назначение некоторых наиболее важных векторов:

Номер Описание
0 Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). DOS обычно при обработке этого прерывания выводит сообщение об ошибке и останавливает выполнение программы. Для процессора 8086 при этом адрес возврата указывает на следующую после команды деления команду, а в процессоре 80286 - на первый байт команды, вызвавшей прерывание.
1 Прерывание пошагового режима. Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после выполнения команды MOV в сегментные регистры или после загрузки сегментных регистров командой POP.
2 Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора.
3 Прерывание для трассировки. Это прерывание генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания.
4 Переполнение. Генерируется машинной командой INTO, если установлен флаг OF. Если флаг не установлен, то команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций.
5 Печать копии экрана. Генерируется при нажатии на клавиатуре клавиши PrtScr. Обычно используется для печати образа экрана. Для процессора 80286 генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона.
6 Неопределенный код операции или длина команды больше 10 байт (для процессора 80286).
7 Особый случай отсутствия математического сопроцессора (процессор 80286).
8
9 IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных от клавиатуры.
A
B
C
D
E
F
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
71
72 IRQ10 - зарезервировано.
73 IRQ11 - зарезервировано.
74 IRQ12 - зарезервировано.
75
76
77 IRQ15 - зарезервировано.
78 - 7F Не используются.
80-85 Зарезервированы для BASIC.
86-F0 Используются интерпретатором BASIC.
F1-FF Не используются.

IRQ0 - IRQ15 - это аппаратные прерывания, о них будет рассказано позже.

4.3. Маскирование прерываний

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

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

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

4.4. Изменение таблицы векторов прерываний

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

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

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

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

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

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

Для чтения вектора используйте функцию 35h прерывания 21h. Перед ее вызовом регистр AL должен содержать номер вектора в таблице. После выполнения функции в регистрах ES:BX будет искомый адрес обработчика прерывания.

Функция 25h прерывания 21h устанавливает для вектора с номером, находящимся в AL, обработчик прерывания DS:DX.

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

Для пользователей языка Си библиотека Quick C содержит функции _dos_getvec(), _dos_setvect(). Первая функция получает адрес из таблицы векторов прерываний, вторая устанавливает новый адрес.

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

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

В библиотеке Quick C имеется функция для организации цепочки прерываний - _chain_intr().

Рассмотрим более подробно возможности библиотеки интегрированной среды Quick C, предназначенные для работы с прерываниями.

Модификатор interrupt (_interrupt для Quick C 2.5 и C 6.0) описывает функцию, которая является обработчиком прерывания. Такая функция завершается командой возврата из обработки прерывания IRET, и для нее автоматически генерируются команды сохранения регистров на входе и их восстановления при выходе из обработчика прерывания. Пример использования модификатора для описания функции обработки прерывания:

void interrupt far int_funct(void) { // Тело обработчика прерывания }

Функция обработки прерывания должна быть FAR-функцией, т.к. таблица векторов прерываний содержит полные адреса в виде сегмент:смещение.

Ключевое слово interrupt используется также для описания переменных, предназначенных для хранения векторов прерываний:

void (_interrupt _far *oldvect)(void);

Модификаторы _interrupt и _far для Quick C 2.5 и C 6.0 являются синонимами соответственно interrupt и far.

Какие требования предъявляются к программе обработки прерывания?

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

Для установки своего обработчика прерываний используйте функцию _dos_setvec. Эта функция имеет два параметра - номер прерывания и указатель на новую функцию обработки прерывания. Например:

_dos_setvect(0x16, my_key_intr);

В этом примере для клавиатурного прерывания с номером 16h устанавливается новый обработчик прерывания my_key_intr.

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

old_vector = _dos_getvect(0x16);

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

Следующий простой пример иллюстрирует применение всех трех функций, предназначенных для работы с прерываниями. Эта программа встраивает собственный обработчик прерывания таймера, который будет вызываться примерно 18,2 раза в секунду. Встраиваемый обработчик прерывания считает тики таймера и, если значение счетчика кратно 20, на динамик компьютера выдается звуковой сигнал. В конце работы новая программа обработки прерывания таймера вызывает старый обработчик с помощью функции _chain_intr.

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

#include #include #include // Выключаем проверку стека и указателей #pragma check_stack(off) #pragma check_pointer(off) // Это макро используется для выдачи // сигнала на внутренний динамик // компьютера. Используется вывод // в формате TTY символа BELL (7) // через прерывание BIOS 10h #define BEEP() _asm { _asm mov bx,0 _asm mov ax, 0E07h _asm int 10h } void main(void); // Объявление программы обработки прерывания void _interrupt _far timer(void); // Эта переменная предназначена для хранения // старого значения вектора прерывания // таймера. Она должна быть глобальной. void (_interrupt _far *oldvect)(void); // Переменная для подсчета тиков таймера volatile long ticks; void main(void) { ticks=0L; // Сбрасываем счетчик тиков таймера oldvect = _dos_getvect(0x1c); // Запоминаем адрес // старого обработчика // прерывания _dos_setvect(0x1c, timer); // Устанавливаем свой // обработчик printf("nТаймер установлен. Нажмите любую" "клавишу...n"); getch(); // Ожидаем нажатия на любую клавишу _dos_setvect(0x1c,oldvect); // Восстанавливаем старый // обработчик прерывания // таймера exit(0); } // Функция обрабатывает прерывания таймера void _interrupt _far timer(void) { ticks++; // Увеличиваем счетчик тиков таймера // Если значение счетчика тиков кратно 20, // выдаем сигнал на динамик компьютера if((ticks % 20) == 0) BEEP(); // Вызываем старый обработчик прерывания _chain_intr(oldvect); }

4.5. Особенности обработки аппаратных прерываний

Аппаратные прерывания вырабатываются устройствами компьютера, когда возникает необходимость их обслуживания. Например, по прерыванию таймера соответствующий обработчик прерывания увеличивает содержимое ячеек памяти, используемых для хранения времени. В отличие от программных прерываний, вызываемых запланировано самой прикладной программой, аппаратные прерывания всегда происходят асинхронно по отношению к выполняющимся программам. Кроме того, может возникнуть одновременно сразу несколько прерываний!

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

Система приоритетов реализована на двух микросхемах Intel 8259 (для машин класса XT - на одной такой микросхеме). Каждая микросхема обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.

Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15 (для машин класса XT существуют только уровни IRQ0 - IRQ7).

Для машин XT приоритеты линейно зависели от номера уровня прерывания. IRQ0 соответствовало самому высокому приоритету, за ним шли IRQ1, IRQ2, IRQ3 и так далее. Уровень IRQ2 в машинах класса XT был зарезервирован для дальнейшего расширения системы и, начиная с машин класса AT, IRQ2 стал использоваться для каскадирования контроллеров прерывания 8259. Добавленные приоритетные уровни IRQ8 - IRQ15 в этих машинах располагаются по приоритету между IRQ1 и IRQ3.

Приведем таблицу аппаратных прерываний, расположенных в порядке приоритета:

Номер Описание
8 IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду.
9 IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных с клавиатуры.
A IRQ2 - используется для каскадирования аппаратных прерываний в машинах класса AT.
70 IRQ8 - прерывание от часов реального времени.
71 IRQ9 - прерывание от контроллера EGA.
72 IRQ10 - зарезервировано.
73 IRQ11 - зарезервировано.
74 IRQ12 - зарезервировано.
75 IRQ13 - прерывание от математического сопроцессора.
76 IRQ14 - прерывание от контроллера жесткого диска.
77 IRQ15 - зарезервировано.
B IRQ3 - прерывание асинхронного порта COM2.
C IRQ4 - прерывание асинхронного порта COM1.
D IRQ5 - прерывание от контроллера жесткого диска для XT.
E IRQ6 - прерывание генерируется контроллером флоппи-диска после завершения операции.
F IRQ7 - прерывание принтера. Генерируется принтером, когда он готов к выполнению очередной операции. Многие адаптеры принтера не используют это прерывание.

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

Для управления схемами приоритетов необходимо знать внутреннее устройство контроллера прерываний 8259. Поступающие прерывания запоминаются в регистре запроса на прерывание IRR. Каждый бит из восьми в этом регистре соответствует прерыванию. После проверки на обработку в настоящий момент другого прерывания запрашивается информация из регистра обслуживания ISR. Перед выдачей запроса на прерывание в процессор проверяется содержимое восьмибитового регистра маски прерываний IMR. Если прерывание данного уровня не замаскировано, то выдается запрос на прерывание.

Наиболее интересными с точки зрения программирования контроллера прерываний являются регистры маски прерываний IMR и управляющий регистр прерываний.

В машинах класса XT регистр маски прерываний имеет адрес 21h, управляющий регистр прерываний - 20h. Для машин AT первый контроллер 8259 имеет такие же адреса, что и в машинах XT, регистр маски прерываний второго контроллера имеет адрес A1h, управляющий регистр прерываний - A0h.

Разряды регистра маски прерываний соответствуют номерам IRQ. Для того чтобы замаскировать аппаратное прерывание какого-либо уровня, надо заслать в регистр маски байт, в котором бит, соответствующий этому уровню, установлен в 1. Например, для маскирования прерываний от НГМД в порт 21h надо заслать двоичное число 01000000.

Приведем пример программы, маскирующей прерывание от флоппи-диска:

#include #include #include void main(void); void main(void) { outp(0x21,0x40); printf("nПрерывания от флоппи-диска запрещены.n"); exit(0); }

Эта программа есть на дискете, прилагающейся к книге. Запустите ее (с жесткого диска) и попробуйте поработать, например, с дисководом А:. У вас ничего не получится!

Чтобы "оживить" флоппи-диски, запустите программу, которая размаскирует все прерывания (в том числе и от флоппи):

#include #include #include void main(void); void main(void) { outp(0x21,0); printf("nПрерывания от флоппи-диска разрешены.n"); exit(0); }

Заметьте, что мы только что замаскировали прерывание именно от флоппи-диска, все остальные устройства продолжали нормально работать. Если бы мы выдали машинную команду CLI, то отключились бы все аппаратные прерывания. Это привело бы, например, к тому, что клавиатура была бы заблокирована.

Еще одно замечание, касающееся обработки аппаратных прерываний. Если вы полностью заменяете стандартный обработчик аппаратного прерывания, не забудьте в конце программы выдать байт 20h в порт с адресом 20h (A0h для второго контроллера 8259). Эти действия необходимы для очистки регистра обслуживания прерывания ISR. При этом разрешается обработка прерываний с более низким приоритетом чем то, которое только что обрабатывалось.

Если вы обрабатываете прерывание 1Ch, то добавка в конце программы не нужна, так как это прерывание является расширением другого прерывания (прерывания таймера).

Перед тем, как завершить изучение прерываний, зададимся вопросом - можно ли замаскировать немаскируемое прерывание? Оказывается можно!

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

Для XT маскированием немаскируемого прерывания управляет порт с адресом 0A0h. Если записать в него 0, немаскируемое прерывание будет запрещено, если 80h - разрешено.

Аналогично для AT маскированием немаскируемого прерывания управляет бит 7 порта 70h. Запись байта 0ADh в порт 70h запретит немаскируемое прерывание, а байта 2Dh - разрешит прохождение прерывания.

Заметим, что мы не запрещаем немаскируемое прерывание "внутри" процессора - это невозможно по определению, мы "не пускаем" сигнал прерывания на вход NMI.