Описание процессора i8086 для программиста

       

Идентификация источников прерываний


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

– по обнаружению ошибки во время выполнения инструкций деления DIV и IDIV (“штатная” причина для прерывания по этому вектору);

– по инструкции INT 0;

– при поступлении сигнала внешнего маскируемого прерывания, сопровождаемого передачей нулевого номера вектора прерывания[5].

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

Используемый в персональных компьютерах контроллер прерываний на базе микросхем типа 8259 (эмулируемый современными чипсетами) фиксирует факт обслуживания прерывания по каждой из своих линий запросов прерываний. Обработчик прерывания должен проверить состояние соответствующего внутреннего регистра контроллера прерываний, чтобы определить, послужил ли причиной прерывания внешний запрос или какое-нибудь событие внутри программы. Естественно, что если данному вектору прерывания не соответствует какая-либо линия запроса внешнего прерывания (IRQ), то и произойти это прерывание по внешнему запросу не может.

При прерывании по ошибке деления (вектор 0) сохранённый в стеке адрес будет указывать на команду деления, вызвавшую прерывание, в то время как при выполнении инструкции INT 0 – на следующую за ней инструкцию, которая также может оказаться командой деления. Необходимо проанализировать код команды, на которую указывает сохранённый в стеке адрес инструкции – если это не команда деления, то причиной прерывания является инструкция INT 0. Если же сохранён адрес команды деления, то требуется “ручная” проверка её параметров. Если они окажутся корректными, то прерывание возникло из-за инструкции INT 0, непосредственно предшествующей команде деления.
Если же параметры некорректны, причиной могла послужить и предшествовавшая инструкция INT 0, и инструкция деления. Совершенно однозначная идентификация в такой ситуации невозможна: хотя последние два байта, предшествующие команде деления, могут совпасть с кодом команды INT 0 (CD 00), нельзя поручиться, что эти байты не являются частью многобайтового кода какой-нибудь другой команды.

Чтобы определить, произошло ли прерывание по вектору 1 в результате трассировки выполнения программы с помощью флажка TF или из-за выполнения инструкции INT 1, нужно проверить состояние флажка TF в содержимом регистра FLAGS, сохранённом в стеке в процессе прерывания. Если этот флажок там сброшен, прерывание было вызвано инструкцией INT 1. Если же флажок был установлен, то имело место прерывание трассировки, что, однако, не исключает вероятности того, что одновременно была выполнена и инструкция INT 1. Однозначная идентификация в такой ситуации невозможна по той же причине, что и для вектора 0.

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

Прерывания по векторам 3 и 4 могут быть программно идентифицированы однозначно: они происходят либо из-за выполнения однобайтовых инструкций INT3 и INTO

(коды CC и CE соответственно), либо из-за двухбайтовых инструкций INT 3 и INT 4

(коды CD 03 и CD 04 соответственно).

Таким образом, в общем случае абсолютно точно идентифицировать источник прерывания по векторам 0–2 невозможно. Как уже упоминалось, фирма Intel зарезервировала векторы 0–31 для “внутренних нужд” микропроцессора; часть из них задействована в современных образцах процессоров.Поэтому настоятельно не рекомендуется использовать инструкции INT

с номерами 0–31, а также назначать этим векторам маскируемые аппаратные прерывания.


Содержание раздела