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

7.1. Прерывания

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

Процессор определяет необходимость обработки внешнего прерывания по наличию сигнала на одном из контактов INTR# или NMI#. При появлении сигнала на линии INTR# внешний контроллер прерываний (например, 8259A) должен предоставить процессору вектор (номер) прерывания. С линией NMI# всегда связано прерывание с номером 2. В процессорах Pentium+ эти линии могут быть сконфигурированы на использование APIC (Advanced Programmable Interrupt Controller), тогда они называются LINT0 и LINT1 и информация по ним передается в виде сообщений в специальном формате.

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

Прерывания, которые генерируются при поступлении сигнала на вход INTR#, называют маскируемыми аппаратными прерываниями. Бит IF в регистре флагов позволяет заблокировать (замаскировать) обработку таких прерываний.

Прерывания, генерируемые сигналом NMI#, называют немаскируемыми аппаратными прерываниями. В процессорах Pentium+ немаскируемое прерывание может быть сгенерировано при получении специального сообщения по шине APIC. Немаскируемые прерывания не блокируются флагом IF. Пока выполняется обработчик немаскируемого прерывания процессор блокирует получение немаскируемых прерываний до выполнения инструкции IRET, чтобы исключить одновременную обработку нескольких немаскируемых прерываний. Рекомендуется вызывать этот обработчик через шлюз прерывания, тогда на время его выполнения будут также заблокированы маскируемые прерывания.

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

Несмотря на возможность спекулятивного выполнения, присущую архитектуре P6+, в прерванной программе сохраняется порядок выполнения инструкций, заложенный программистом. Это обеспечивается механизмом "отката" (retirement phase).

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

С помощью инструкции INT n (n - номер прерывания) можно сгенерировать прерывание с любым номером 0...255. Такие прерывания называют программными. Состояние бита IF в регистре флагов не влияет на возможность генерации программных прерываний.

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