Прерывания и исключения

Прерывания и исключения нарушают нормальный ход выполнения программы для обработки внешних событий или сигнализации о возникновении особых условий или ошибок. По прерыванию или исключению процессор сохраняет в стеке регистр (E)FLAGS и указатель CS:(E)IP на ту инструкцию, которую он должен будет выполнить после обработки прерывания. Этой инструкцией будет следующая за той, во время исполнения которой произошло прерывание, или та же самая (в защищенном режиме при возникновении ряда исключений в стеке сохраняется еще и код ошибки). После сохранения этих значений процессор переходит к исполнению кода обработчика данного прерывания (исключения), определяя точку входа в него через номер (0-255) по таблице прерываний. Номер элемента в таблице прерываний называется вектором прерывания, он определяется источником прерывания (исключения). Обработчик прерывания (исключения) должен заканчиваться специальной инструкцией возврата IRET, по которой из стека восстанавливается указатель CS:(E)IP и прежнее значение флагов. Для исключений, в которых сохраняется и код ошибки, обработчик до выполнения инструкции IRET должен извлечь из стека код ошибки. Различают четыре источника прерываний.
  1. Внутренние прерывания (исключения) процессора и сопроцессора; вектор определяется типом произошедшего события.
  2. Немаскируемые внешние прерывания по входу NMI; вектор фиксирован (01).
  3. Маскируемые внешние прерывания по входу INT (или по шине APIC); вектор передается контроллером прерываний.
  4. Программно-вызываемые прерывания; вектор определяется в команде.

Последние из этого списка в прямом смысле прерываниями не являются, поскольку представляют собой лишь специфический способ вызова процедур – не по адресу, а по его номеру в таблице, причем независимо от состояния флага IF. Программные прерывания широко используются для вызовов сервисов BIOS и ОС – это компактно и удобно.
В начале отработки любого (в том числе и программного) прерывания процессор сбрасывает флаг разрешения прерываний IF. Процедура обработки завершается инструкцией IRET, по которой из стека восстанавливаются автоматически сохраненные регистры (в восстановленном регистре флагов прерывания разрешены) и  процессор начинает выполнение инструкции, следующей за той, после которой исполнялось прерывание. Конечно, программно во время обслуживания прерывания возможно умышленное или случайное изменение указателя или содержимого стека, и тогда инструкция IRET «отправит» процессор по другому адресу, в результате чего компьютер может и зависнуть. Если на время обработки требуется реакция и на другие прерывания, обработчик должен установить флаг IF. Прерывания, обслуживаемые до завершения обработки предыдущего, называются вложенными. Вложенные прерывания могут создавать опасность переполнения стека, поскольку каждое «вложение» будет использовать его для своих целей. Переполнение стека может также являться причиной зависаний. Длинные процедуры обработки со сброшенным флагом IF могут привести к потере системного времени, поскольку «часы» операционной системы используют аппаратные прерывания от таймера. Процедура обслуживания для каждого источника аппаратных прерываний должна быть написана весьма осмотрительно и учитывать нюансы работы остальных подсистем.
Маскируемые внешние прерывания обрабатываются процессором по сигналу на входе INT только при установленном флаге разрешения прерываний IF.
Немаскируемые прерывания обрабатываются процессором независимо от состояния флага разрешения прерывания IF. К ним относятся прерывания, по линии NMI (Non-Maskable Interrupt), а для процессоров, поддерживающих режим системного управления, еще и по линии SMI# (System Management Interrupt).
Внутренние прерывания процессора (исключения) генерируются при возникновении особых условий выполнения текущей инструкции. В большинстве своем они не столько асинхронны, сколько неожиданны для исполнения программного кода. Номер вектора определяется процессором в зависимости от происхождения исключения.
Каждому номеру (0-255) прерывания или исключения соответствует элемент в таблице дескрипторов прерываний IDT (Interrupt Descriptor Table). В реальном режиме таблица прерываний содержит дальние адреса (двойные слова) обслуживающих процедур и после сброса располагается, начиная с нулевых адресов. В защищенном режиме таблица IDT содержит 8-байтные дескрипторы прерываний, может хранить от 32 до 256 дескрипторов и располагаться в любом месте физической памяти.
Под исключения (внутренние прерывания) в процессорах Intel резервируются векторы 0-31 в таблице прерываний, однако в PC часть из них перекрывается системными прерываниями – сервисами BIOS и DOS, а также аппаратными прерываниями. Эти перекрытия особенно неприятны для защищенного режима; они усложняют процедуры обработчиков прерываний.
Для обработки аппаратных прерываний в многопроцессорных системах традиционные аппаратные средства становятся непригодными, поскольку прежняя схема подачи запроса INTR и передачи вектора в цикле INTA* явно ориентирована на единственность процессора. Для решения этой задачи в процессоры, начиная со второго поколения Pentium, введен расширенный программируемый контроллер прерываний APIC (Advanced Programmable Interruption Controller).
загрузка...