7. Прерывания и исключения    
 СОДЕРЖАНИЕ
 Введение
 1. Развитие архитектуры
 2. Структура МП
 3. Ресурсы МП
 4. Управление памятью
 5. Защита
 6. Многозадачность
 7. Прерывания и исключения
 8. Инициализация МП
 9. Эмуляция 8086
 Глоссарий
 ПРАКТИКА
 1. Семантический разрыв
 2. CPUID
 3. Защищенный режим
 Вопросы и задания

7.2. Исключения

Источниками исключений являются три типа событий:

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

Процессоры Pentium+ предоставляют зависящий от реализации механизм контроля операций внутри чипа и транзакций на шине процессора, называемый машинным контролем. Если при выполнении машинного контроля возникает ошибка, генерируется исключение #18.

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

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

Ловушка возникает на границе команд сразу же после команды, вызвавшей это исключение. Значения регистров CS и EIP, заносимые в стек обработчика, указывают на очередную команду. Например, если ловушка сработала на команде JMP, то в стеке запоминаются значения регистров CS и EIP, указывающие на адресат команды JMP.

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

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

Типичным случаем аварии является исключение #8 "двойная ошибка". Двойная ошибка происходит, когда процессор пытается обработать исключение, а его обработчик генерирует еще одно исключение. Для некоторых исключений процессор не генерирует двойную ошибку, такие исключения называют "легкими": 1, 2, 3, 4, 5, 6, 7, 9, 14 и 16. Только ошибки деления (исключение #0) и сегментные исключения (10, 11, 12, 13), называемые "тяжелыми", могут вызвать двойную ошибку. Таким образом, получение исключения "неприсутствие сегмента" во время обработки исключения отладки не приведет к двойной ошибке, в то время как ошибка сегмента, происходящая во время обработки ошибки деления на нуль, приведет к исключению #8.

Если при попытке вызвать обработчик исключения #8 возникает ошибка, процессор переходит в режим отключения (shutdown mode). Вывести из этого режима процессор могут только аппаратные сигналы: NMI#, SMI#, RESET# или INIT#. Обычно чипсет, обнаружив на шине процессора цикл отключения, инициирует аппаратный сброс.

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

Приоритеты событий:

ПриоритетОписание
1Аппаратный сброс (RESET#) и машинный контроль (#18)
2Ловушка при переключении задач (#1)
3Внешний сигнал (INIT#, SMI# и др.)
4Контрольная точка (#3) и ловушка отладки (#1)
5Аппаратные прерывания (NMI#, INTR#)
6Нарушения, обнаруженные при предвыборке очередной инструкции:
  • точка отладки по коду (#1),
  • неприсутствие страницы с кодом (#14),
  • превышение предела сегмента кода (#13).
7Нарушения, обнаруженные при декодировании очередной инструкции:
  • превышение длины инструкции (#13),
  • недействительный код операции (#6),
  • неприсутствие сопроцессора (#7).
8Нарушения, обнаруженные при исполнении инструкции (все остальные)

Назначение прерываний и исключений:

номерописаниетипвозможен рестарткод ошибки источник исключения
0Ошибка делениянарушениеданет DIV, IDIV
1Отладканарушение / ловушкаданет любая команда
2NMIпрерываниесо след. командынет сигнал NMI
3Контрольная точкаловушкасо след. командынет INT3
4Переполнениеловушкасо след. командынет INTO
5Нарушение границы массиванарушениеданет BOUND
6Недействительный код операциинарушениеданет Инструкция UD2 (P6+), неверный код операции, неверный операнд, выполнение спец. команд в RM, неверное использование префикса LOCK
7Сопроцессор отсутствуетнарушениеданет ESC, WAIT
8Двойное нарушениеавариянет0 Если при обработке тяжелого исключения1 или страничного нарушения возникает еще одно тяжелое исключение.
9Нарушение сегмента для сопроцессора2 нарушениеданетESC, WAIT
10Недействительный TSSнарушениедаесть JMP, CALL, IRET, INT
11Неприсутствие сегментанарушениедаесть при попытке загрузить сегментный регистр или LDTR
12Нарушение стеканарушениедаесть операции со стеком, загрузка SS
13Нарушение общей защитынарушение / ловушкадаесть любое обращение к памяти или проверка защиты
14Страничное нарушениенарушениедаесть любое обращение к памяти
15резерв
16Ошибка сопроцессоранарушениеданет ESC, WAIT
17Контроль выравнивания3нарушениеда0 любое обращение к данным в памяти
18Машинный контроль4авариястоп зависит от МПзависит от МП
19Ошибка SIMD5нарушениеданет инструкция SSE или SSE2
20-31резерв
32-255Определяемые пользователем прерыванияпрерываниеда- INT n или внешний сигнал

1К тяжелым относят исключения 0, 10, 11, 12, 13.

2Это исключение генерируется только МП 80386. В поздних процессорах - зарезервировано.

3Используется в i486 и выше.

4Используется в Pentium и выше.

5Используется в Pentium-III и выше.