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

Прерывание
(hardware interrupt)
 —
это событие, генерируемое внешним (по
отношению к процессору) устройством.
Посредством аппаратных прерываний
аппаратура либо информирует центральный
процессор о том, что произошло событие,
требующее немедленной реакции (например,
пользователь нажал клавишу), либо
сообщает о завершении операции ввода
вывода (например, закончено чтение
данных с диска в основную память). Каждый
тип аппаратных прерываний имеет
собственный номер, однозначно определяющий
источник прерывания. Аппаратное
прерывание — это асинхронное событие,
то есть оно возникает вне зависимости
от того, какой код исполняется процессором
в данный момент. Обработка аппаратного
прерывания не должна учитывать, какой
процесс или поток является текущим.
Исключительная
ситуация
(exception) —
событие, возникающее в результате
попытки выполнения программой команды,
которая по каким-то причинам не может
быть выполнена до конца. Примерами таких
команд могут быть попытки доступа к
ресурсу при отсутствии достаточных
привилегий или обращение к отсутствующей
странице памяти. Исключительные ситуации,
как и системные вызовы, являются
синхронными событиями, возникающими в
контексте текущей задачи. Исключительные
ситуации можно разделить на исправимые
и неисправимые. К исправимым относятся
такие исключительные ситуации, как
отсутствие нужной информации в оперативной
памяти. После устранения причины
исправимой исключительной ситуации
программа может выполняться дальше.
Возникновение в процессе работы
операционной системы исправимых
исключительных ситуаций считается
нормальным явлением. Неисправимые
исключительные ситуации чаще всего
возникают в результате ошибок в программах
(например, деление на ноль). Обычно в
таких случаях операционная система
реагирует завершением программы,
вызвавшей исключительную ситуацию.

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

Если
при работе с внешним устройством
вычислительная система не пользуется
методом опроса его состояния, а задействует
механизм прерываний,
то при возникновениипрерывания,
как мы уже говорили раньше, процессор,
частично сохранив свое состояние,
передает управление специальной
программе обработки прерывания.
Мы уже рассматривали действия операционной
системы над процессами, происходящими
при возникновении прерывания,
в разделе «Переключение контекста»
лекции 2, где после
возникновения прерывания осуществлялись
следующие действия: сохранение контекста,
обработка прерывания,
планирование использования процессора,
восстановление контекста. Тогда мы
обращали больше внимания на действия,
связанные с сохранением и восстановлением
контекста и планированием использования
процессора. Теперь давайте подробнее
остановимся на том, что скрывается за
словами «обработка прерывания».

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
Буферизация и кэширование

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

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

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

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

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

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

Spooling и захват устройств

О понятии spooling мы говорили в первой лекции нашего курса, как о механизме, впервые позволившем совместить реальные операции ввода-вывода одного задания с выполнением другого задания. Теперь мы можем определить это понятие более точно. Под словом spool мы подразумеваем буфер, содержащий входные или выходные данные для устройства, на котором следует избегать чередования его использования (возникновения interleaving – см. раздел «Interleaving, race condition и взаимоисключения» лекции 5) различными процессами. Правда, в современных вычислительных системах spool для ввода данных практически не используется, а в основном предназначен для накопления выходной информации.

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

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

Обеспечение spooling и механизма захвата устройств является прерогативой базовой подсистемы ввода-вывода.

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

Если при работе с внешним устройством вычислительная система не пользуется методом опроса его состояния, а задействует механизм прерываний, то при возникновении прерывания, как мы уже говорили раньше, процессор, частично сохранив свое состояние, передает управление специальной программе обработки прерывания. Мы уже рассматривали действия операционной системы над процессами, происходящими при возникновении прерывания, в разделе «Переключение контекста» лекции 2, где после возникновения прерывания осуществлялись следующие действия: сохранение контекста, обработка прерывания, планирование использования процессора, восстановление контекста. Тогда мы обращали больше внимания на действия, связанные с сохранением и восстановлением контекста и планированием использования процессора. Теперь давайте подробнее остановимся на том, что скрывается за словами «обработка прерывания «.

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

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

Планирование запросов

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

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

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

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

Эта глава описывает механизмы прерываний и обработки исключений при работе в защищённом режиме на процессорах Intel 64 или IA-32. Большая часть информации из этой главы также применима для режимов: реальных адресов(real address), виртуального (virtual-8086) и 64-битного.

Глова 15, “8086 Эмуляция”, описывает особенности механизмов прерываний и исключений в реальном режиме и виртуальном-8086 режиме. Секция 5.14, “Обработчики исключений и прерываний в 64-битном режиме”, описывают особенности механизмов прерываний и исключений в режимах IA-32e и в подрежиме 64-бита.

Введение в прерывания и исключения[]

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

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

Исключения появляются, когда идет выполнение инструкции и процессор сумел распознать ошибочную ситуацию, такую как деление на ноль. Процессор распознаёт различные типы ошибок, включая: нарушения защиты, сбойные страницы, и внутренние ошибки машины. Механизм проверки процессоров: Pentium 4, Intel Xeon, семейства P6, Pentium — спроектирован так, что допускает генерацию исключений, когда происходят внутренние аппаратные ошибки и ошибки в шинах.

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

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

Вектора исключений и прерываний[]

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

Процессор использует вектор, назначенный на исключение или прерывание как индекс в таблице дескрипторов прерываний (IDT). Таблица обеспечивает точку входа в программу обработки исключения или прерывания ( см. Раздел 5.10, “ Таблица дескрипторов прерываний (IDT)”).

Доступный диапазон номера вектора от 0 до 255. Векторы в диапазоне 0 до 31 зарезервированы архитектурами Intel 64 и IA-32 для реализации своих исключений и прерываний. В настоящее время не все векторы в этом диапазоне имеют определённый функционал.

Незадействованные векторы из этого диапазона зарезервированы. Не используйте зарезервированные вектора.

Векторы в диапазоне 32 — 255 определены как пользовательские прерывания и не зарезервированы для архитектур Intel 64 и IA-32. Эти прерывания в основном предназначены для внешних устройств ввода — вывода, чтобы дать этим устройствам возможность посылать прерывания процессору через один из внешних механизмов аппаратных прерываний ( см. Раздел 5.3, “Источники прерываний”).

Таблица 5-1 показывает, для чего предназначаются вектора архитектурно определённых исключений и прерываний NMI. Эта таблица задает тип исключения (см. Раздел 5.5, “Классификация исключений”), и указывает, наличие код ошибки в стеке обработчика исключения. Каждомуисточнику предопределённого исключения и NMI также назначается вектор прерывания.

Источники прерываний[]

Процессор получает прерывания от двух источников:

• Внешние прерывания (генерируемые аппаратурой).

• Программно-генерируемые прерывания.

Внешние прерывания[]

Внешние прерывания поступают от контактов на процессоре или через локальный APIC. Первопричинными контакты прерываний на процессорах: Pentium 4, Intel, Xeon, семействе P6, и Pentium — являются контакты LINT[1:0], которые связаны с локальными APIC(см. Главу 8, “Расширенный Программируемый Контроллер Прерывания (APIC)”). Когда APIC контроллер задействован, контакты LINT[1:0] могут быть запрограммированы через локальную векторную таблицу(LVT) APIC’а. Эти контакты будут связаны с любым исключением процессора или векторами прерывания.

Если локальный APIC глобально / аппаратно заблокирован, то используются контакты INTR и NMI соответственно. Возбуждение контакта INTR сообщает процессору, что внешнее прерывание произошло. Затем процессор читает с системной шины число — вектор прерывания, посланное внешнем контроллером прерывания, таким как 8259A (см. Раздел 5.2, “Векторы исключений и прерываний”). Возбужденный контакт NMI сообщает о немаскируемом прерывании (NMI), которому назначен вектор прерывания 2.

{C}Таблица 5-1. Прерывания и исключения защищённого режима.

Номер вектора

Обозна-чение

Описание Тип Код ошибки Источник
0 #DE Ошибки деления Ошибка
(Fault)
Нет Команды DIV и IDIV
1 #DB Debug; Отладка Ошибка / Ловушка
(Fault/ Trap)
Нет Любой код или данные или инструкция INT 1.0
2 Прерывание NMI Прерывание
(Interrupt)
Нет Немаскируемое внешнее прерывание
3 #BP Breakpoint; точки останова Ловушка
(Trap)
Нет Команда INT 3
4 #OF Overflow; Переполнение Ловушка
(Trap)
Нет Команда INTO
5 #BR BOUND Range Exceeded;Выход за диапазон Ошибка
(Fault)
Нет Команда BOUND
6 #UD Неизвестный Опкод (неправильный опкод) Ошибка
(Fault)
Нет Команда UD2 или

Зарезервированный опкод1

7 #NM Устройство не доступно (отсутствует сопроцессор) Ошибка
(Fault)
Нет Команды с плавающей точкой или WAIT/FWAIT
8 #DF Двойная ошибка аварийное прекращение работы (Abort) Да
(ноль)
Любая команда, которая способна генерировать исключение, NMI или INTR.
9 Переполнение сегмента сопроцессора(зарезервировано) Ошибка
(Fault)
Нет Команды с плавающей точкой2
10 #TS Неправильный TSS Ошибка
(Fault)
Да Переключение задач или обращение к TSS
11 #NP Сегмент отсутствует Ошибка
(Fault)
Да При загрузке сегментного регистра или при обращении к сегменту
12 #SS Ошибка сегмента стека Ошибка
(Fault)
Да При операции со стеком или загрузке в регистр SS
13 #GP Ошибка общей защиты Ошибка
(Fault)
Да Любое обращение к памяти и другие проверки защиты.
14 #PF Страничная ошибка Ошибка
(Fault)
Да Любое обращение к памяти
15 Зарезервировано Intel. Не использовать Нет
16 #MF Ошибка с плавающей точкой на FPU x87 (Ошибка вычислений) Ошибка
(Fault)
Нет Команды с плавающей точкой или WAIT/FWAIT
17 #AC Проверка выравнивания Ошибка
(Fault)
Да
(ноль)
Любое обращение к данным в памяти.3
18 #MC Проверка машины аварийное прекращение работы (Abort) Нет Коды ошибки (если есть) и источник зависит от модели 4
19 #XF Исключение плавающей точки в SIMD Ошибка
(Fault)
Нет Команды для работы с плавающей точкой в расширениях SSE/SSE2/SSE3.5
20-31 Зарезервировано Intel. Не использовать.
32-255 Определяются пользователем. (Не зарезервированы) Прерывание
(Interrupt)
Внешнее прерывание или инструкция INT n

ПРИМЕЧАНИЯ:

0. Прим переводчика. Начиная с документации на PIV это прерывание обозначено как: Зарезервированное. Источник: только для использования Intel.

1. Команда UD2 была введена в процессоре Pentium Pro.

2. Процессоры новее Intel386 не генерируют это исключение.

3. Это исключение было введено в процессоре Intel486.

4. Это исключение было введено в процессоре Pentium и расширено в процессорах семейства P6.

5. Это исключение было введено в процессоре Pentium III.

{C}Локальный APIC процессора обычно соединен с основным системным I/O APIC. Здесь внешние прерывания, полученные с контактов I/O APIC могут быть направлены к локальному APIC через системную шину (процессор Pentium 4 и процессор Intel Xeon) или последовательную шину APIC’ов (семейства процессоров P6 и процессоры Pentium). I/O APIC определяет вектор-номер прерывания и посылает этот номер локальному APIC. Когда система содержит много процессоров, процессоры могут также послать прерывания друг другу посредством системной шины (процессоры Pentium 4 и Intel Xeon) или через последовательную шину APIC’ов (процессоры семейства P6 и процессоры Pentium).

На процессорах Intel486 и более ранних процессорах Pentium, которые не содержат на чипе локальный APIC, контакты LINT [1:0] не доступны. Эти процессоры имеют узкоспециализированные контакты NMI и INTR. У таких процессоров, внешние прерывания типично генерируются основным системным контроллером прерывания (8259A), от которого сигналы о прерывании поступают на контакт INTR.

Замечание. Некоторые другие контакты процессора также могут заставлять процессор генерировать прерывания. Однако, эти прерывания не обрабатываются механизмами прерываний и исключений, описанными в этой главе. Это такие контакты как RESET#, FLUSH#, STPCLK#, SMI#, R/S#, и INIT#. Включены ли они в специфический процессор, зависит от реализации процессора. Функции контактов описаны в справочниках для индивидуальных процессоров. Контакт SMI# описан в Главе 24, “Системное управление(System Management).”

Маскируемые аппаратные прерывания[]

Любое внешнее прерывание, которое поступает к процессору посредством контакта INTR или через локальный APIC, называют маскируемым аппаратным прерыванием. Маскируемые аппаратные прерывания, это такие прерывания которые поступают через контакт INTR, к ним относят все вектора определенные в архитектуре IA-32 с номерами от 0 до 255;а также и те которые поступают непосредственно от локального APIC и имеют вектора прерываний 16 — 255.

Флаг IF в регистре EFLAGS позволяет замаскировать все маскируемым аппаратным прерывания как группу (одни разом всех) (см. Секцию 5.8.1, “Маскировка Маскируемых Аппаратных прерываний”). Примечание, что, когда прерывания 0 до 15 поступают через локальный APIC, APIC сигнализирует о получении неправильного вектора.

Прерывания генерируемые программным обеспечением[]

Команда INT n генерирует прерывание изнутри программного обеспечения, используя номер вектора прерывания как операнд. Например, команда INT 35 принудительно вызывает программу обработки для прерывания 35.

Любой из векторов прерывания от 0 до 255 может использоваться как параметр в этой команде. Если известный вектор NMI будет использоваться, то ответ процессора не будет тем же самым, как если бы это прерывание NMI было бы сгенерированного нормальным способом. Если вектор номер 2 (вектор NMI) используется в этой команде, вызывается программа обработки прерывания NMI , но аппаратные средства обработки NMI в процессоре не активируются.

Прерывания, сгенерированные в программном обеспечении при помощи команды INT n не могут быть замаскированы при помощи флага IF в регистре EFLAGS.

Источники исключений[]

Процессор получает исключения из трех источников:

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

• Сгенерированные программным обеспечением исключения.

• Исключения при проверке машины.

Исключения от программных ошибок[]

Процессор генерирует одно или более исключений, когда он обнаруживает ошибки в процессе работы прикладной программы или операционной системе. Архитектуры Intel 64 и IA-32 определяют номера векторов для каждого обнаруживаемого процессором исключения. Исключения классифицированы как ошибки (faults), ловушки(tarp), и аварийные прекращения работы(aborts) ( см. Секцию 5.5, “Классификация исключений”).

Исключения сгенерированные программным обеспечением[]

Команды INTO, INT 3, и BOUND генерируют исключения в программном обеспечении. Эти команды позволяют отметить точки в потоке команд, в которых будут выполнять исключения. Например, INT 3 являет причиной генерации исключение точка-остановка (breakpoint).

Команда INT n может использоваться, чтобы подражать исключениям в программном обеспечении; но есть ограничение. Если INT n использует вектор для одного из архитектурно-определенных исключений, процессор генерирует прерывание к правильному вектору (чтобы получить доступ к обработчику особых ситуаций), но не помещает код ошибки в стек. Если так случилось, а стандартное аппаратное исключение должно предоставлять код ошибки. То обработчик исключений все еще будет пытаться вытолкнуть код ошибки из стека, обрабатывая исключение. Поскольку никакой код ошибки не был помещен, при этом обработчик вытолкнет прочь EIP(вместо недостающего кода ошибки) и тем самым испортит точку возврата. Это приведёт к возврату в неправильное местоположение.

Исключения проверки машины[]

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

Для получения дополнительной информации о механизме проверки машины, см. Главу 5, “Прервите №18 — Исключение при проверке машины (#MC)” и Главу 14, “Архитектура проверки машины”.

Классификация исключений[]

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

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

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

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

Примечание

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

Рестарт программы или задачи[]

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

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

Для исключений класса «ловушки» указатель адреса возвращения указывает на команду после команды попавшей в ловушку. Если ловушка обнаружена в течение команды, которая передает выполнение, указатель команды возврата отражает передачу. Например, если ловушка обнаружена, выполняя команду JMP, указатель команды вернет указатель на адресата команды JMP (к той, на которую нацелена JMP), а не к следующему адресу после команды JMP. Все исключения ловушки позволяют выполнить рестарт программы или задачи без потери непрерывности. Например, исключение переполнения — исключение ловушки. Здесь, указатель команды возврата указывает на команду после команды INTO, которая проверила EFLAGS.OF флаг переполнения. Обработчик ловушки для этого исключения решает проблему состояния переполнения. По возвращению от обработчика ловушки, программы или задачи процессор продолжает выполнять команды которые идут после INTO.

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

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

Способность семейства процессоров P6,паралельно выполнить команды не затрагивает вызов прерываний процессором. Прерывания вызываются на границах команд, расположенных в течение фазы приостановки выполнения команды; таким образом они всегда выполняются в «упорядоченном» потоке команд. См. Главу 2, “Архитектуры Intel® 64 и IA-32,” в Intel® 64 и Руководстве Разработчика Программного обеспечения Архитектуры IA-32, Томе 1, для получения дополнительной информации о семейной микроархитектуре процессоров P6 и ее поддержке неупорядоченному выполнению команд.

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

Немаскируемое прерывание (NMI- NONMASKABLE INTERRUPT)[]

Немаскируемое прерывание (NMI) может быть сгенерировано в любом из двух случаев:

• Внешние аппаратные средства дергают контакт NMI.

• процессор получает сообщение на системной шине (процессоров Pentium 4 и Intel Xeon) или APIC последовательная шина (процессоров семейства P6 и процессоры Pentium) с режимом доставки равным NMI.

Когда процессор получает NMI от любого из этих источников, процессор обрабатывает это немедленно, вызывая обработчик NMI, на который указывает вектор прерывания номер 2. Процессор также предпринимает определенные условия на аппаратном уровне чтобы обеспечить, возможность беспрерывной работы, чтобы никакие другие прерывания, включая прерывания NMI, не были получены, пока обработчик NMI не закончил выполнение ( см. Секцию 5.7.1, “Обработка многократных NMI’и” ).

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

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

Обработка многократных NMI’й[]

В то время как программа обработки прерывания NMI выполняется, процессор запрещает дополнительные вызовы обработчиков NMI, пока команда IRET не выполнится. Это блокирование последующего NMI’и предотвращает накопление, вызовов обработчиков NMI’й. Рекомендуется, чтобы программа обработчик прерывания NMI получала доступ через точку входа в прерывание, чтобы запретить маскируемые аппаратные прерывания ( см. Секцию 5.8.1, “Маскирования маскируемых аппаратных прерываний”). Если обработчик NMI — это задача виртуального-8086 с IOPL меньше чем 3, команда IRET, выполненная от обработчика генерирует исключение общей защиты (см. Секцию 15.2.7, “Чувствительные команды”). В этом случае, NMI размаскируется прежде, чем обработчик исключений общей защиты будет вызван.

Разрешение и запрещение прерываний[]

Процессор запрещает генерацию некоторых прерываний, в зависимости от состояния процессора и от состояния флагов IF и RF в регистре EFLAGS, как описано в следующих секциях.

Маскирования маскируемых аппаратных прерываний[]

Флаг IF может запретить обслуживание маскируемых аппаратных прерываний, полученных процессором через контакт INTR или через локальный APIC ( см. Секцию 5.3.2, “Маскируемые аппаратные прерывания”). Когда, флаг IF очищен, процессор запрещает доставленные прерываний от контакта INTR, или через локальный APIC от генератора внутреннего запроса на прерывание; когда, флаг IF установлен, прерывания , поставленные от INTR или через локальный APIC от генератора внутреннего запроса на прерывание разрешаются; такие прерывания будут обработаны как нормальные внешние прерывания.

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

Также как и другие флаги регистра EFLAGS, процессор очищает флаг IF при приходе аппаратного сброса.

Факт, что группа маскируемых аппаратных прерываний включает в себя зарезервированные прерывание и исключения с векторы от 0 до 32, может потенциально привести к замешательству. Архитектурно, когда флаг IF установлен, прерывание для любого из векторов от 0 до 32 можно доставить процессору через контакт INTR, и любой из векторов от 16 до 32 можно доставить через локальный APIC. Процессор тогда генерирует прерывание и вызывает прерывание или обработчик исключений с указанным номером вектора. Так например, возможно вызвать обработчик отсутствующей страницы через контакт INTR (посредством вектора 14); однако, это не истинное исключение отсутствия страницы. Это — прерывание. Как и в случае с INT n командой (см. Секцию 5.4.2, “Сгенерированные программным обеспечением Исключения”), когда прерывание сгенерировано через контакт INTR с вектором исключения, процессор не помещает код ошибки в стек, таким образом, обработчик исключений, возможно, не будет правильно работать.

Флаг IF может быть установлен или очищен при помощи соответствующих команд STI (set interrupt — enable flag; установка флага разрешения прерывания), и CLI (clear interrupt — enable flag; очистка флага разрешения прерывания). Эти команды могут выполниться, только если текущий уровень привилегий равен или меньше чем IOPL. Если эти инструкции выполняются, когда текущий уровень привилегий больше чем IOPL, то будет сгенерировано исключение общей защиты (#GP). Когда включено расширение виртуальное режима, установлен флаг VME в регистре контроля CR4, тогда эффект IOPL на этих командах немного изменяется: см. Секцию 15.3, “Обработчики прерываний и исключений в виртуальном-8086 режиме”. На поведение также воздействует флажок PVI: см. Секцию 15.4, “Виртуальные прерывания в защищённом режиме.”

Флаг IF также задействуется при следующих операциях:

• При выполнение команды PUSHF. Она сохраняет все флаги в стеке, где они могут быть исследованы и изменены. Команда POPF может использоваться, чтобы загрузить измененные флаги обратно в регистр EFLAGS.

• При переключение задач или вызове команд POPF и IRET происходит загрузка регистра EFLAGS; поэтому, они могут использоваться, чтобы изменить значение флага IF.

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

См. описания команд CLI, STI, PUSHF, POPF, и IRET в Главе 3, “Описание система команд, A-M,” в Руководстве Разработчика Программного обеспечения Архитектур IA-32 и Intel® 64, томе 2A, для детального изучения работы этих команд, по изменению флага IF.

Маскировка команд точка-остановка (Breakpoints).[]

Флаг RF в регистре EFLAGS управляет реакцией процессора на состояние «команда точка-остановка» (см. описание флага RF в Секции 2.3, “Системные флаги и поля в регистре EFLAGS”).

Когда он установлен, то препятствует генерированию исключения отладки (#DB) для команд точка-остановка; когда очищено, команды точка-остановка генерируюют исключения отладки. Первичная функция флага RF это препятствовать процессору зацикливать исключения отладки на команде точка-остановка. Для получения дополнительной информации о использовании этого флага. См. Секцию 18.3.1.1, “Условия исключения у команд точека-остановка”.

Маскировка исключений и прерываний, при переключении стеков[]

Для перехода к другому сегменту стека, программное обеспечение часто использует пару команд, например:

MOV SS, AX

MOV ESP, StackTop

Если прерывание или исключение происходит после того, как селектор сегмента был загружен в регистр SS, но прежде, чем регистр ESP был загружен, то эти две части логического адреса в пространство стека противоречивы для вызова прерывания или обработчика исключения.

Чтобы предотвращать эту ситуацию, процессор запрещает: прерывания, исключения отладки, и пошаговые исключения-ловушки. Запрет начинает действовать после применения команды MOV к регистру SS или POP к SS, и действует до того момента, пока не перейдет последнюю границу следующей команды. Все другие ошибки все еще могут сгенерироваться. Если для изменения содержания регистра SS используется команда LSS (которая является рекомендованным методом изменения этого регистра), то этой проблемы не возникает.

Приоритет среди одновременных исключений и прерываний[]

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

Приоритет Описание
1 (наивысший) Аппаратный сброс и проверки машины

-RESET (сброс)

— проверки машины

2 Ловушки при переключении задач

-Флаг T установлен в TSS

3 Внешние аппаратные воздействия

— FLUSH

— STOPCLK

— SMI

— INIT

4 Ловушка на предыдущей инструкции

— Точка остановки (Breakpoints)

— Ловушки исключения отладки(Установлен флаг TF или данные/I-O breakpoint)

5 Немаскируемые прерывания (NMI)1
6 Маскируемые аппаратные средства.1
7 Ошибка в коде точки остановки.
8 Ошибки при выборке следующей команды

— Нарушение предела сегмента-кода

— Ошибка страницы с кодом

9 Ошибки при декодирования следующей команды

— Длина команды> 15 байтов

— Недействительный Опкод

— Сопроцессор не доступен

10 (низший) Ошибки при выполнении команды

— Переполнение

— ошибка BOUND

— Неправильный TSS

— Сегмент не Подарок

— Ошибка стека

— Общая Защита

— Отсутствие страницы Данных

— Проверка выравнивания

— Исключение в FPU x87 при работе с плавающей точкой

— SIMD исключение с плавающей точкой

  1. процессор Intel486 ™ и более ранние процессоры объединяют немаскируемые и маскируемые прерывания в один класс приоритетов.

В то время как приоритет среди этих классов, перечисленных в Таблице 5-2 непротиворечив всюду по архитектуре, исключения в пределах каждого класса являются зависящими от выполнения и могут измениться с процессора на процессор. Процессор обрабатывает первыми ждущие обработки исключения или прерывания, который имеет самый высокий приоритет по классу, передавая выполнение первой команде обработчика. От исключений с более низким приоритетом процессор отказывается; более низкие по приоритету прерывания находятся в ожидании. Исключения от которых отказались, повторно генерируются, когда программа обработки прерывания возобновляет выполнение программы или задачи, где исключения и/или прерывания произошли.

Таблица описателей прерываний(INTERRUPT DESCRIPTOR TABLE (IDT))[]

Таблица описателей прерываний (IDT) связывает каждый вектор исключение или прерывания с описателем точки входа в процедуру или задачу, которая обслуживает связанное исключение или прерывание. Точно также как GDT и LDTы, IDT представляет собой массив 8-байтовых описателей (в защищенном режиме). В отличие от глобальной таблицы описателей(GDT), первый элемент таблицы описателей прерываний(IDT) может содержать действующей описатель. Чтобы сформировать смещение в таблице описателей прерываний, процессор масштабирует вектор исключение или прерывания на восемь (число байтов в описателе). Поскольку есть только 256 векторов прерываний или исключений, таблица дескрипторов прерываний не должна содержать больше чем 256 описателей. Но она может содержать меньше чем 256 описателей, потому что описатели требуются только для векторов прерывания и векторов исключения, которые могут произойти. Все пустые элементы в таблице описателей прерываний(IDT) должны иметь флаг существования установленный в 0.

Базовые адреса таблицы описателей прерываний(IDT) должны быть выровнены на 8-байтовой границе, чтобы получить максимальную производительность при заполнении строк кэша. Значение предела выражено в байтах и добавляется к базовому адресу, чтобы получить адрес последнего допустимого байта. Значение предела 0 соответствует 1 допустимому байту. Поскольку элементы таблицы описателей прерываний всегда в длину восемь байт, предел должен всегда быть меньше чем число кратное восьми (то есть, 8N — 1).

IDT может постоянно находиться где-нибудь в линейном адресном пространстве. Как показано на рисунке 5.1, процессор определяет местонахождение таблицы IDT, используя регистр IDTR. Этот регистр содержит 32-разрядный базовый адрес и 16-разрядный предел для таблицы описателей прерываний IDT.

LIDT (load IDT register) и SIDT (store IDT register) команды загружают и хранят содержание регистра IDTR, соответственно. Команда LIDT загружает IDTR регистр c базовым адресом и пределом, находящиеся в операнде типа память. Эта команда может выполниться только, когда текущий уровень привилегий (CPL) равен 0. Это обычно исполняется кодом инициализации операционной системы, при создании таблице описателей прерываний(IDT). Операционная система также может использовать эти команды, чтобы изменить одну IDT на другую. Команда SIDT копирует значение базового адреса и предела из IDTR в память. Эта команда может выполниться в любом уровне привилегий. Если вектор ссылается на описатель вне предела таблицы дескрипторов прерываний, то генерируется исключение общей защиты (#GP).
Замечание
Поскольку прерывания поставляют ядру процессора только однажды, неправильно сконфигурированная таблица описателей прерываний(IDT) может привести к неполному обрабатывающему прерыванию и/или блокированию доставки прерывания. Архитектуры IA-32 требуют исполнения ниже следующих правил установить поля base/limit/access в IDTR и каждую поле в описателях IDT. То же самое требует архитектура Intel 64. Эти правила включает неявную ссылку на наличие сегмента кода адресата в GDT или LDT и доступ к стеку.

Рис 5.1

Рисунок 5.1. Взаимодействие IDTR и IDT.

Описатели таблицы прерываний (IDT)[]

IDT может содержать любой из трех видов описателей точек входа:

описатель точки входа в задачу&nbsp

  • описатель точки входа в прерывание&nbsp
  • описатель точки входа в ловушку

На рисунок 5.2. показаны форматы этих описателей. Описатели точки входа в задачу используемые в IDT имеет формат — тот же самый как у описателя точки входа в задачу используемой в GDT или LDT (см. Раздел 6.2.5, “Описатель точки входа в задачу”). Описатель точки входа в задачу содержит селектор сегмента, указывающий TSS для задачи обработчика прерывания и/или исключения. Точки входа в прерывание и ловушку, очень похожи на точки входа по вызову процедуры (см. Раздел 4.8.3, “Точки входа по вызову”). Они содержат дальний указатель (селектор сегмента и смещение), это используется процессором, чтобы передать выполнение программы в процедуру обработки исключения — или прерывания находящейся в кодовом сегменте. Процессор будет работать по разному в зависимости от типа точки и наличия флага IF в регистре EFLAGS (см. Раздел 5.12.1.2, “Использование регистра флагов в процедурном обработчике исключения или прерывания”).

Рис 5.2

Рисунок 5.2. Описатели IDT.

Обработчики исключений и прерываний[]

Процессор обрабатывает вызовы в программу обработчик исключения и прерывания подобно тому, как делает обработку вызовов сделанных командой CALL к процедуре или задаче. Реагируя на исключение или прерывание, процессор использует вектор исключение или прерывания как индекс в IDT. Если индекс указывает на точку входа в процедуру прерывание или точка входа в процедуру ловушке, процессор вызывает обработчик исключение или прерывания в манере аналогичной команде CALL или вызову точки входа в процедуру (см. раздел 4.8.2, “Описатели точек входа”, затем раздел 4.8.6, “Возврат из вызванной процедуры”). Если индекс указывает на точку входа в задачу, процессор выполняет переключение задач к задаче обрабатывающей исключение или прерывания способом подобным команде CALL точки входа в задачу (см. раздел 6.3, «Переключение задач»).

Процедурная обработка исключений или прерываний[]

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

Рис 5.3

Рисунок 5.3. Вызов процедуры прерывания.

Затем процессор выполняет вызов процедурного обработчика исключения или прерывания:

  • Если процедура обработчика должна выполняться в цифровой форме с более низком уровнем привилегий, при этом происходит смена стека. Затем когда переключение стеков происходит выполняются следующие пункты:
    • a. Селектор сегмента и указатель вершины стека, которые будут использоваться обработчиком, будут загружен из TSS для в настоящее время выполняющейся задачи. Поэтому в этот новый стек, процессор помещает селектор сегмента стека и указатель на вершину стека прерванной процедуры.
       
    • b. Процессор тогда сохраняет текущее состояние регистров EFLAGS, CS, и EIP в новом стеке (см. рисунок 5.4.).
       
    • c. Если исключение создаёт код ошибки, то он помещается в текущий стек после значения EIP.
  • Если процедура обработчика собирается выполняться с тем же самым уровнем привилегий как прерванная процедура:
    • a. Процессор сохраняет текущее состояние регистров EFLAGS, CS и EIP на текущем стеке (см. рисунок 5.4.).
       
    • b. Если исключение создаёт код ошибки, то он помещается в текущий стек после значения EIP.

Рисунок 5 4
Рисунок 5.4. Использование стека при переходе к процедуре обработке прерывания или исключения.

Чтобы вернуться из процедурного обработчика исключения или прерывания, обработчик должен использовать команду IRET (или IRETD). Команда IRET подобна команде RET за исключением того, что она восстанавливает сохраненные флаги в регистре EFLAGS. Поле IOPL регистра EFLAGS восстанавливается, только если текущий уровень привилегий — 0. Флаг IF изменяется, только если текущий уровень привилегий меньше или равен чем уровень привилегий ввода-вывода (IOPL). Чтобы получить полные описания операций выполняемых командой IRET, то см. Главу 3, “Справочная информация о системе команд A-M», из руководства разработчика программного обеспечения архитектур Intel® 64 и IA-32, Том 2A. Если при вызове процедурного обработчика произошло переключение стека, то команда IRET возвращает исходный стек на место по возвращению.

Защита процедурных обработчиков исключений и прерываний[]

Защита уровня привилегий для процедур обработки исключения и прерывания подобна используемому для обычных вызовов процедуры когда их вызывают через точки входа по вызову (см. Раздел 4.8.4, “Доступ к сегменту кода через точки входа по запросу в процедуру”). Процессор не разрешает передачу выполнения к процедуре обработки исключению или прерывания в менее привилегированной сегмент кода (в цифровой форме в уровень привилегий с большей цифрой) чем текущий уровень привилегий.

Попытка нарушить это правило приводит к исключению общей защиты (#GP). Механизм защиты для обработчиков исключения и прерываний имеет следующие особенности:

  • поскольку вектора прерываний и исключений не имеют никакого RPL, RPL не проверяется при неявных вызовах обработчиков исключений и прерываний.
  • процессор проверяет DPL прерывания или точки входа в ловушку, только если исключение или прерывание были сгенерированы от команд: INT n, INT 3, или INTO. Здесь, текущий уровень привилегий должен быть меньше чем или равным DPL точки входа. Это ограничение предотвращает возможность прикладной программе или процедуре, выполняющиеся в уровне привилегий 3 выполнить программное прерывание, чтобы обратиться к важным обработчикам исключений, типа обработчика отсутствия страницы, если этот обработчик помещено в более привилегированный сегмент кода (в цифровой форме более низкий уровень привилегий). Для аппаратных прерываний и исключений обнаруженных

процессором, процессор игнорирует DPL прерывания и точки входа в ловушку.

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

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

Изменяемые флаги в процедурном обработчике исключения или прерывания[]

При доступе к обработчику исключений или обработчику прерываний через точку входа в прерывание или через точку входа в ловушку, процессор очищает флаг TF в регистре EFLAGS после того, как это сохранит содержимое регистра EFLAGS в стеке. (При вызовах в обработчик исключения и обработчик прерывания, процессор также очищает флаги VM, RF, и NT в регистре EFLAGS, после того, как они будут сохранены в стеке.) Очистка флага TF препятствует тому, чтобы трассировка инструкций влияла на прерывание. Последующая инструкция IRET восстанавливает флаги TF, VM, RF, и NT к значениям сохраненным в содержимого регистра EFLAGS из стека.
Единственная разница между точками входа в прерывания и точками входа в ловушки — это способ, которым процессор обрабатывает, флаг IF в регистре EFLAGS. При доступе к процедурному обработчику исключения или прерывания через точку входа в прерывания, процессор очищает флаг IF, чтобы препятствовать тому, чтобы другие прерывания вмешались в текущею обработку прерывания. Последующая инструкция IRET восстанавливает, флаг IF к его значению сохраненному в содержимом регистра EFLAGS из стека. Доступ к процедурному обработчику через точку входа в ловушку не влияет на флаг IF.

Задачные обработчики прерываний[]

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

  • любой контекст прерванной программы или задачи автоматически сохраняется.
  • новый TSS разрешает обработчику использовать новый стек с уровнем привилегий равным 0, обрабатывая исключение или прерывание. Если исключение или прерывание происходят, когда текущий уровень привилегий равен 0 и стек разрушен, то обращение к обработчику через точку входа в задачу, может предотвратить системный аварийный отказ, предоставляя обработчику новый стек с нулевым уровнем привилегий.
  • Ещё обработчик может быть изолирован от других задач, давай возможность использовать отдельное адресное пространство. Это осуществимо если воспользоваться отдельными LDT.

Недостаток обработки прерывания в отдельной задаче — то, что количество машинных параметров, которые должны быть сохранены при переключении задач, огромно что делает обработку прерываний медленнее, чем если бы использовались процедурные обработчики прерываний.
Точка входа в задачу в таблице описателей прерываний(IDT) ссылаются на описатель TSS в глобальной таблице описателей(GDT) (см. рисунок 5.5.). Переключение к задачному обработчику выполняется тем же самым способом что и при обычным переключение задач (см. Раздел 6.3, «Переключение задач»). Ссылка на предыдущую прерванную задачу сохраняется в поле ссылки на предыдущую задачу в TSS задачи обработчика. Если исключение вызывает генерацию кода ошибки, то этот код ошибки копируется в стек новой задачи.

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

Замечание
Поскольку задачи архитектуры IA-32 не повторно используемые, то задачный обработчик прерывания должен отключать прерывания на время своей работы пока не закончит обработку прерывания командой IRET. Это действие препятствует появлению друго прерыванию, в то время пока как сегмент состояния задачи(TSS) прерывания все еще работает, в противном случае будет сгенерировано исключение общей защиту (#GP).

Рисунок 5.5. Переключение задач при прерывание.

Код ошибки[]

Когда условие исключения связано с определенным сегментом, процессор помещает код ошибки в стек обработчика исключений (независимо от того процедурный или задачный). Формат кода ошибки показан на рисунке 5.6. Код ошибки напоминает селектор сегмента; однако, вместо флага TI и поля RPL, код ошибки содержит 3 флага:

EXT — Внешнее событие (бит 0) — Когда установлено, указывает, что событие, внешнее к программе, такое как аппаратное прерывание, вызвало исключение.

IDT — Расположение описателя (бит 1) — Когда установлено, указывает, что индексная часть кода ошибки указывает на описатель точки входа в IDT; когда очищено, указывает, что индекс ссылается на описатель в GDT или текущем LDT.

TI — GDT/LDT (бит 2) — Только используется, когда флаг IDT сброшен. Если флаг TI установлен , то индексная часть кода ошибки указывает на сегмент или описатель точки входа в LDT; когда флаг очищен, то индекс указывает на описатель в GDT.

Рисунок. 5.6. Код ошибки.

Индексное поле селектора сегмента, используется как индекс в IDT, или GDT, или текущей LDT к сегменту или селектору точки входа, ссылаемому кодом ошибки. В некоторых случаях код ошибки — нуль (то есть, все биты в более низком слове будут очищены в ноль). Нулевой код ошибки указывает, что ошибка не была вызвана обращением к определенному сегменту или то, что во время работы произошло обращение к нулевому описателю сегмента.

Формат кода ошибки отличается для исключений отсутствия страницы (#PF). См. раздел в этой главе: “Прерывание 14 — Исключение отсутствия страницы (#PF)”.

Код ошибки заноситься в стеке как двойное слово или слово (в зависимости размера по умолчанию для точки входа в прерывания, ловушку или задачу). Для 32 разрядного кода, чтобы сохранить стек выровненным на двойном слове, код ошибки расширяется до 32 бит. Верхняя половина кода ошибки зарезервирована. Замечание, когда инструкция IRET выполняется, код ошибки не извлекается из стека. Таким образом, чтобы выполнить возврат из обработчика исключений, обработчик должен удалить код ошибки прежде, чем выполнить возврат.

Код ошибки не помещается в стек для исключений, которые сгенерированы внешними источниками (от контактов INTR или LINT [1:0]) или команды INT n, даже если он предусмотрен.

Обработка исключений и прерываний в 64-разрядном режиме[]

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

  • Все обработчики прерываний, на которых указывает IDT, находятся в 64-разрядном коде (это не применяется к обработчику SMI).
  • Операций(push, pop) со стеком прерывания теперь стали 64 битыми; процессор использует 8 байтов, при необходимости расширяя данные нулями.
  • Указатель вершины стека (SS:RSP) в любом случае помещается в стек обработчика прерываниях. В унаследованных режимах эта операция зависит от наличия изменения текущего уровня привилегий (CPL).
  • Если есть изменение в CPL, то новый SS устанавливается в нуль.
  • Изменено поведение IRET.
  • Появился новый механизм переключателя стека прерывания.
  • Выравнивание стекового фрейма прерывания отличается.

IDT 64-разрядного режима[]

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

Рисунок 5.7. Описатель точки входа в 64-разрядной IDT.

В 64-разрядном режиме смещение в IDT формируется, масштабирования вектора прерывания на 16. Первые восемь байтов (байты 7:0) 64-битного режима точки входа в прерывание подобны, но не идентичны унаследованным 32-битным точкам входам в прерывания. Поле типа (биты 11:8 в байтах 7:4) описано в таблице 3.2. Таблица Стека Прерывания (Interrupt Stack Table — IST) поле (биты 4:0 в байтах 7:4) используется механизмами переключения стека, описанными в разделе 5.14.5, “Таблица стека прерывания.” Байты 11:8 содержат верхние 32 бита целевого RIP (смещение сегмента прерывания) в канонической форме. Исключение общей защиты (#GP), генерируется, если программное обеспечение пытается использовать на точку входа в прерывания с целевым RIP, который не находится в канонической форме.
Целевой сегмент кода, на который ссылается точка входа в прерывание, должен быть 64-разрядным сегментом кода (CS.L = 1, CS.D = 0). Если цель не 64-разрядный сегмент кода, то будет сгенерировано — исключение общей защиты (#GP), при этом код ошибки будет содержать вектор IDT в числовой форме.
Только на 64-разрядное прерывание и точки входа в ловушки могут использоваться в режиме IA-32e (64-разрядный режим и режим совместимости). Унаследованные 32-разрядное прерывание или точки входа в ловушки (0EH или 0FH) пересмотрены в режиме IA-32e как 64-разрядные прерывания и точки входа в ловушки. В режиме IA-32e не существует никаких 32-разрядный прерываний и точек входа в ловушки. Если обращение идёт на 16-разрядное прерывание или точку входа в ловушку (06H или 07H), то будет сгенерировано исключение общей защиты (#GP (0)).

Стековый фрейм в 64-разрядном режиме[]

В унаследованном режиме размер записи IDT (16 битов или 32 бита) определяет размер для push стекового фрейма прерывания. Значение SS:ESP помещается в стек только при изменении CPL. В 64-разрядном режиме размер push стекового фрейма прерывания фиксирован и равен восьми байтам. Это так, потому что разрешено использовать только на 64-битные точки входа(gates). В 64-разрядном режиме безоговорочно помещается значение SS:RSP в стек, а не только при изменении CPL.

Кроме кода ошибки, безоговорочное помещение в стек значения SS:RSP дарит операционным системам одинаковый размер стекового фрейма прерывания для всех прерывания. Прервите точки входа в служебную программу, которые обрабатывают прерывания сгенерированные инструкцией INTn, или внешним сигнал INTR# также могут поместить дополнительно код ошибки для того, чтобы сделать размер стека одинаковым везде.

В унаследованном режиме указатель вершины стека может быть выравнен на любом значение, когда случается прерывание или исключение при формировании стекового фрейма. Это приводит к тому что стековый фрейм и последующие значения помещённые в стеке будут выравнены произвольно. В режиме IA-32e RSP выравнивается к 16-байтовой границе прежде, чем поместит в стек стековый фрейм прерывания. Сам стековый фрейм — выравнивается на 16-байтовой границе, когда происходит вызов обработчика прерывания. Процессор может принудительно поменять значение нового RSP при прерываниях, потому что предыдущее значение RSP безоговорочно сохранено на недавно выровненном стеке. Предыдущее значение RSP будет автоматически восстановлено последующей командой IRET.

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

Хотя выравнивание RSP всегда выполняется, когда LMA = 1, это имеет место только для случая привилегированного режима, где нет никакого переключателя стека или использования IST. Для переключателя стека или IST, ОС по-видимому поместила бы соответственно выровненные значения RSP в TSS.

IRET в режиме IA-32e[]

В режиме IA-32e IRET выполняется с операндам имеющим 8-байтую разрдность. Это не потому что так захотелось, это принудительное требование. Стек отформатирован таким способом, чтобы соответствовал IRET, чтобы 8-байтовая разрядность операнда IRET работала правильно.

Поскольку стековый фрейм прерывания всегда кратен восьми байтам в режиме IA-32e, IRET должен выталкивать восьмибайтовые элементы из стека. Это достигается, префиксом 64-битного размера операнда перед IRET. Разрядность инструкции POP определяется адресным-размером инструкции. Размер корректировки SS/ESP/RSP определяется разрядностью стека.

Когда IRET выполняется в 64-битном режиме, то значение SS:RSP безоговорочно извлекается из стекового фрейма. В режиме совместимости IRET выталкивает SS:RSP из стека, только если есть изменение CPL. Это позволяет унаследованным приложениям выполняться должным образом в режиме совместимости при использовании инструкции IRET. Если использовать 64-битный IRET, то будет безоговорочное извлечение SS:RSP прочь из стекового фрейма прерывания, даже если целевой сегмент кода работает в 64-разрядном режиме или в CPL = 0. Это — то, потому что исходное прерывание всегда помещает SS:RSP в стек.

В режиме IA-32e IRET позволяют загрузить нулевой SS при определенных условиях. Если целевой режим — 64-разрядный режим и целевой CPL <> 3, IRET позволяет загрузить нулевой селектор в SS. Часть механизма переключателя стека, прерывания или исключения устанавливает новый SS в NULL, вместо того, чтобы выбрать новый селектор SS от TSS и загрузить соответствующий дескриптор из GDT или LDT. Новый селектор SS, устанавливается в NULL, чтобы должным образом обработать возврат из последующих вложенных далеких переходах. Если сама вызываемая процедура прервана,то нулевой SS помещается в стековый фрейм. На последующем IRET нулевой SS в стеке действует как флаг, чтобы сказать процессору: «не загружай новый описатель SS».

В оглавлении перечислены более-менее в логическом порядке статьи об экспериментах с разработкой ОС.

  • Эксперименты с загрузкой Операционной Системы
    • Operation System boot experiments
    • Загрузка операционной системы Hello world
    • Ассемблер и ядро Операционной Системы
    • Вторичный загрузчик Операционной Системы
    • Experimenting with OS Kernel Loading using Menuet OS boot loader
    • Protected Mode Kernel Hello World
    • Схема адресации в защищенном режиме
    • Переключение в защищенный режим в загрузчике
  • Разработка собственного загрузчика для FAT32
    • FAT32 загрузчик, загрузка с флешки (начало разработки)
    • Чтение секторов физического диска под Windows
    • Вывод значений регистров на ассемблере в загрузчике
    • MBR загрузчик в режиме LBA
    • Преобразование из LBA в CHS и обратно. MBR загрузчик в режиме CHS
    • Предварительные эксперименты с чтением FAT32 на C под Windows
      • Чтение FAT32 на С под Windows
      • Чтение FAT32 на С под Windows, продолжение
      • Чтение FAT32 под Windows на Си (продолжение 2)
      • Чтение FAT32 под Windows на C (заключение)
    • FAT32 загрузчик, загрузка с флешки (результат)
  • Эксперименты с ядром
    • GCC Calling conventions investigation
    • Изменение соглашений передачи параметров функций в gcc (Function attributes)
    • GCC Inline Assembly Experiments
    • Экранные функции в ядре ОС
    • Обработка прерываний исключений и прерываний в защищённом режиме
      • Обработка исключений и прерываний — обзор
      • Вектора прерываний и исключений
      • Источники прерываний
      • Таблица прерываний защищённого режима
      • Маскируемые прерывания
      • Источники исключений
      • Классификация исключений процессора
      • Рестарт программы или задачи при обработке исключения
      • Не маскируемые прерывания
      • Запрет и разрешение прерываний
      • Приоритезация одновременных прерываний в процессоре
      • Таблица дескрипторов прерываний IDT
      • Дескрипторы прерываний IDT gate дескрипторы
      • Обработка исключений
      • Передача кода ошибки в обработчик исключения
      • Справочник по исключениям
        • Interrupt 0—Divide Error Exception (#DE)
        • Interrupt 1—Debug Exception (#DB)
        • Interrupt 2—NMI Interrupt
        • Interrupt 3—Breakpoint Exception (#BP)
        • Interrupt 4—Overflow Exception (#OF)
        • Interrupt 5—BOUND Range Exceeded Exception (#BR)
        • Interrupt 6—Invalid Opcode Exception (#UD)
        • Interrupt 7—Device Not Available Exception (#NM)
        • Interrupt 8—Double Fault Exception (#DF)
        • Interrupt 9—Coprocessor Segment Overrun
        • Interrupt 10—Invalid TSS Exception (#TS)
        • Interrupt 11—Segment Not Present (#NP)
        • Interrupt 12—Stack Fault Exception (#SS)
        • Interrupt 13—General Protection Exception (#GP)
        • Interrupt 14—Page-Fault Exception (#PF)
        • Interrupt 16—x87 FPU Floating-Point Error (#MF)
        • Interrupt 17—Alignment Check Exception (#AC)
        • Interrupt 18—Machine-Check Exception (#MC)
        • Interrupt 19—SIMD Floating-Point Exception (#XM)
        • Interrupts 32 to 255—User Defined Interrupts
    • Архитектура обработки исключений в IBM PC Compatible системах
    • Другие статьи по OSDev…

Пришла пора продолжить серию постов об экспериментах с разработкой Операционной Системы. У меня есть загрузчики, есть билд-система для сборки ядра. Есть заготовка экранных функций. Загрузчик загружает ядро в память по адресу 0x10000, переводит процессор в защищенный режим и передает управление на ядро. Ядро в данный момент просто выводит на экран несколько отладочных сообщений в цикле. Эдакий сферический конь в вакууме. Работает этот «конь» недолго. Дело в том, что у компьютера по-умолчанию настроены ряд прерываний. В частности таймер. Это прерывание вызывается весьма часто. В момент старта компьютер работает в реальном режиме. И прерывания обрабатываются обработчиками прерываний реального режима. Таблица прерываний реального режима находится в адресах 0 — 0x400.

В защищённом режиме, прерывания обрабатываются по-другому. У меня кода обработки прерываний пока нет, поэтому первое же прерывание приводит мою тестовую систему к перезагрузке.

Об обработке прерываний есть статья James Molloy: http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html. Есть ещё другие материалы, но я планирую для начала обратиться к первоисточникам. К документации Intel.

Прерывания и исключения — обзор

Прерывания и исключения — события, означающие что где-то в системе
(оборудовании) или внутри текущей выполняющейся программы или
задачи возникло состояние, требующее немедленного внимания
процессора. Обычно прерывания и исключения приводят к принудительной
передачи управления от текущей выполняемой программы или задачи к
специальной программной процедуре или задаче, называемой
обработчиком прерывания или обработчиком исключения. Действие,
выполняемое процессором в ответ на прерывание или исключение
называют обработка прерывания или исключения (servicing or handling the
interrupt or exception).

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

Исключения возникают когда процессор определяет возникновение ошибки
(detects error condition) в процессе выполнения инструкции. Например —
деление на ноль. Процессор определяет разнообразные error conditions
включая нарушения защиты (protection violations), ошибки страниц (page
faults), internal machine faults. Архитектура процессоров Pentium 4, Intel Xeon,
P6 family и Pentium позволяет генерацию machine-check excheption при
возникновении внутренних аппаратных ошибок (hardware errors) или
ошибок шины (bus errors).

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

Вектора прерываний и исключений

Для упорядочивания обработки исключений и прерываний, каждому
отдельному исключению и каждому прерыванию (interrupt condition),
требующему специальной обработки процессором, назначается уникальный
идентификатор, называемый номером вектора (vector number). Процессор
использует vector number (номер), назначенный исключению или
прерыванию как индекс в таблице дескрипторов прерываний (interrupt
descriptor table IDT). Таблица содержит адреса (entry point) обработчиков
исключений или прерываний.

Разрешенный диапозон для vector numbers от 0 до 255. Номера от 0 до 31
зарезервированы в Intel 64 и IA-32 архитектурах для architecturedefined
прерываний и исколючений. Не все из vector numbers в этом диапозоне
имеют назначенную функцию. Неназначенные vector numbers в этом
диапозоне зарезервированы. Не используйте эти зарезервированные
номера.

Vector numbers в диапозоне от 32 до 255 отведены под user-defined
прерывания и не зарезервированы Intel 64 и IA-32 архитектурами. Эти
прерывания в основном предназначены для внешних устройств ввода-
вывода.

Источники прерываний

Процессор получает прерывания из 2-х источников:
— Внешние (аппаратно генерируемые) прерывания.
— Программно-генерируемые прерывания.

Внешние (аппаратные) прерывания

Внешние прерывания получаются через контакты процессора или через
локальный контроллер прерываний APIC. Главные контакты, означающие
состояние прерывания на процессорах Pentium 4, Intel Xeon, P6 family и
Pentium — LINT[1:0] pins, соединенные с локальным APIC. Когда локальный
APIC включен, LINT[1:0] pins, могут быть запрограммированы с помощью
APIC local vector table (LVT), на ассоциацию с любым процессорным
исключением или вектором прерывания.

Когда локальный APIC является глобальным/аппаратные прерывания
запрещены, тогда эти контакты конфигурируются как INTR и NMI контакты,
соответственно. Сигнал на контакте INTR сигнализирует процессору, что
внешнее прерывание возникло. Процессор читает из системной шины
inerrupt vector, предоставляемый внешним контроллером прерываний,
таким как 8259A. Сигнал на контакте NMI говорит процессору, что
немаскируемое прерывание (NMI), назначенное на вектор прерывания 2.

Прерывания и исключения защищенного режима

Vector No. Mnemonic Description Type Error Code Source
0 #DE Divide Error Fault No DIV и IDIV инструкции
1 #DB RESERVED Fault/Trap No For Intel use only
2 NMI Interrupt Interrupt No Nonmaskable externel
interrupt
3 #BP Breakpoint Trap No INT 3 instruction
4 #OF Overflow Trap No INT0 instruction
5 #BR BOUND Range Exceeded Fault No BOUND instruction
6 #UD Invalid Opcode (Undefined
Opcode)
Fault No UD2 instruction or reserved
opcode
7 #NM Device Not Available (No
Math Coprocessor)
Fault No Floating-point or WIT/FWAIT
instruction
8 #DF Double Fault Abort Yes (zero) Any instruction that can
generate an exception, an NMI, or an INTR.
9 Coprocessor Segment Overrun
(reserved)
Fault No Floating-point instruction
10 #TS Invalid TSS Fault Yes Task switch or TSS access.
11 #NP Segment Not Present Fault Yes Loading segment registers or
accessing system segments.
12 #SS Stack-Segment Fault Fault Yes Stack operations and SS
register loads
13 #GP General Protection Fault Yes Any memory reference and
other protection checks
14 #PF Page Fault Fault Yes Any memory reference
15 (Intel reserved. Do not use) Fault No
16 #MF x87 FPU Floating-Point Error
(Math Fault)
Fault No x87 FPU floating-point or
WAIT/FWAIT instruction
17 #AC Alignment Check Fault Yes(Zero) Any data reference in memory
18 #MC Machine Check Abort No Error codes (if any) and
source are model dependant
19 #XM SIMD Floating-Point Exception Fault No SSE/SSE2/SSE3 floating point
instructions
20-31 Intel reserved. Do not use.
32-255 User Defined ( Non
reserved)
Interrupts
Interrupt External interrupt or INT n
instruction

Внутренний контроллер прерываний процессора localAPIC обычно соединен с
системным контроллером прерываний I/O APIC. Внешние прерывания
полученные через контакты системного контроллера прерываний I/O APIC
могут быть направлены на внутренний контроллер прерываний local APIC
через системную шину (Pentium 4, Intel Core Duo, Intel Core 2, Intel® Atom™,
and Intel Xeon processors) или через APIC serial bus (P6 family and Pentium
processors). Внешний контроллер прерываний I/O APIC определяет vector
number прерывания и шлёт этот номер внутреннему контроллеру
процессора (local APIC). Когда система включает множество процессоров,
процессоры могут также слать прерывания один другому посредством
системной шины (Pentium 4, Intel Core Duo, Intel Core 2, Intel Atom, and
Intel Xeon processors) или посредством APIC serial bus (P6 family and
Pentium processors).

Контакты LINT[1:0] не доступны в процессорах Intel486 и ранних
процессорах Pentium не имеющих встроенного внутреннего local APIC. Эти
процессоры имеют специальные жестко назначенные контакты NMI и INTR.
В системах с такими процессорами прерывания обычно генерируются
системным контроллером прерываний (8259A), с посылкой прерываний
через контакт INTR.

Заметьте, что несколько других контактов на процессоре могут приводить
к возникновению процессорного прерывания. Однако эти прерывания не
обрабатываются механизмом обработки прерываний и исключений
описанным здесь. Эти контакты включают: RESET#, FLUSH#, STPCLK#,
SMI#, R/S#, and INIT#. Есть ли они у конкретного процессора, зависит от
реализации конкретной модели. Функции контактов описаны в технических
описаниях прилагаемых к конкретным процессорам. Контакт SMI#
описывается в главе 26 «System Management».

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

Любое внешнее прерывание доставленное процессору посредством
контакта INTR или через внутренний local APIC называется маскируемым
аппаратным прерыванием. Через Маскируемые аппаратные прерывания
доставленные через контакт INTR могут быть любыми в диапозоне 0 — 255.
Прерывания доставленные через внутренний local API могут быть векторами
в диапозоне 16 — 255.

Флаг IF регистра EFLAGS позволяет маскировать всю группу маскируемых
аппаратных прерываний. При получении прерываний с векторами от 0 до
15 через внутренний local APIC, APIC сообщает (indicates) получение
неверного вектора прерывания.

Источники исключений

Процессор получает исключения из трех источников:
— Обнаруживаемые процессором Program-Error exceptions
— Программно генерируемые исключения
— Machine-check exceptions.

Program-Error Exceptions

Процессор генерирует одно или более исключений при обнаружении
программных ошибок в процессе выполнении приложения, кода
операционной системы или executive. Архитектуры Intel64 и IA-32
определяют vector number для каждого processor-detectable exception.
Исключения подразделяются на faults, traps и aborts.

Программно-генерируемые исключения

Инструкции INTO, INT3 и BOUND позволяют программную генерацию
исключений. Эти инструкции позволяют выполнение проверки условий в
местах выполнения потока инструкций. Например INT 3 вызывает
генерацию breakpoint exception. Инструкция INT n может быть использована
для эмуляции исключений в программах, но есть ограничение. Если INT n
вызывает вектор для одного из architecturally-defined исключений,
процессор генерирует прерывание на корректный вектор (для доступа
к обработчику исключения) но не кладет код ошибки на стек. В отличии
от аппаратно-генерируемое исключения нормально сохраняющего на стеке
код ошибки. Обработчик исключения будет пытаться взять
код ошибки со стека при обработке исключения. Но, так как код ошибки
не был сохранён в стеке, вместо кода ошибки из стека будет извлечён
EIP (на месте пропущенного кода ошибки). Это приведёт к возврату из
обработчика по неверному адресу. (Т.о. нельзя с помощью INT n
обращаться к обработчикам аппаратно-генерируемых исключений).

Machine-Check Exceptions

Процессоры семейств P6 family и Pentium предоставляют внутренние и
внешние machine-check механизмы для проверки операций внутреннего
аппаратного чипа и транзакций шины. Эти механизмы — implementation
dependent (непереносимы). Когда процессор обнаруживает machinecheck
ошибку, процессор сигнализирует об ошибке с помощью machine-check
exception (vector 18) и возвращает код ошибки.

Классификация исключений

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

Продолжение здесь…

Понравилась статья? Поделить с друзьями:
  • Обработка ошибок файлового ввода вывода
  • Обработка ошибок проброс исключений
  • Обработка ошибок перевод
  • Обработка ошибок паскаль
  • Обс выдает ошибку при запуске записи