Прерывания бывают программные (синхронные) и аппаратные (асинхронные).
Аппаратные прерывания делятся на внешние и внутренние (исключения).
Внешние прерывания бывают маскируемые и немаскируемые.
Исключения делятся на три группы:
1). Отказы (faults) – возникают при исполнении команд (например, деление на 0).
2). Ловушки (traps) – возникают после выполнения команд.
3). Выходы из режимов, процессов (abort) – не имеют точного места возникновения.
Механизм обработки прерываний микропроцессором:
1. Запоминает в стеке регистр флагов (EFLAGS), регистры CS и EIP.
2. Определяет номер прерывания по причине. Если прерывание внешнее – номер определяется по сигналу INTR путем обмена данными с контроллером прерываний. Если прерывание программное – номер определяется по команде.
3. Используя таблицу IDT, определяет адрес обработчика прерывания и загружает его в CS:EIP.
4. Выход из прерывания – по команде IRET.
При возникновении исключений № 8, 10-14, 17 микропроцессор заносит в стек 32-разрядный код ошибки.
Обработчики всех исключений, аппаратных и программных прерываний имеют свои дескрипторы, которые хранятся в IDT (Interrupt Descriptor Table).
Структура дескриптора IDT:
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Смещение обработчика прерывания (high) |
Байт доступа |
0 |
Селектор обработчика прерывания |
Смещение обработчика прерывания (low) |
Формирование таблицы IDT:
t_idt = record
off_l, {смещение обработчика прерывания – мл. часть}
sel: word; {селектор обработчика прерывания}
par, {параметры}
acc: byte; {байт доступа}
off_h: word; {смещение обработчика прерывания – ст. часть}
end;
idt: array [0..$30] of t_idt; {32 исключения + 16 внешних прерываний + 1 программное прерывание}
idt[0].off_l := Ofs (exc_00);
idt[0].sel := code_sel;
idt[0].par := 0;
idt[0].acc := $8F;
idt[0].off_h := 0;