Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ППУ_KP.doc
Скачиваний:
32
Добавлен:
26.08.2019
Размер:
134.66 Кб
Скачать

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

Правила замены обработчика прерываний:

  1. Адрес обработчика в таблице векторов прерываний вычисляется как номер вектора прерыванй умноженный на 4, так как каждый элемент таблицы представляет дальний указатель в формате смещение (2 байта по младшему адресу) и сегмента (2 байта по старшему адресу).

  2. Адрес старого обрабочика прерыванй должен в обзяательном порядке сохраняться в памяти программы и восстанаваливаться в таблице векторов прерываний перед выходом из программы.

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

Пример:

old_int dd ?

…………………………………………….

xor AX , AX

mov ES , AX

mov DI , VECTOR_ADDR

mov AX , ES: [DI]

mov [word ptr old_int] , AX ; offset

mov AX , ES: [DI +2]

mov [word ptr old_int+2] , AX ; segment

cli

mov AX , offset NewInt

mov ES: [DI] , AX

mov AX , seg NewInt ; или cs для COM программ

mov ES: [DI+2] , AX

sti

Правила написания обработчив прерываний:

  1. Обработчик прерываний описывается в виде процедуры, выполняющей указанные действия, оканчивающейся командой iret вместо ret. Разница между этими двумя командами состоит в том, что команда iret вынимает из стека не только точку возврата в виде дальнего указателя, но и состояние регистра флагов.

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

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

  4. Передача параметров в обработчик прерываний производиться только посредством глобальных переменных. Исключение составляют только программно инициируемые прерывания, которые вызываются исключительно программными средствами, где параметры передаются через регистры (прерывания DOS и BIOS).

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

  6. При проектировании обработчика прерываний следует учитывать, что все регистры могут иметь случайное значение, в том числе и сегментные регистры за исключением CS, так как обработчик прерывания может прервать другое прервание, которое могло относиться к резидентной программе или участку кода, работающего с другими сегментами данных. Поэтому перед тем как обращаться к переменным следует провести инициализацию соответсвующих сегментных регистров (ES,DS). Для COM программ допускается обращение к данным через сегментный регистр CS.

  7. Во многих случаях обработчик прерываний должен вызывать старый обработчик прерываний, чтобы видоизменять или дополнять его функциональность и обеспечивать целостность работы системы. Если старый обработчик вызывается в начале или конце, то необходимо использовать вызов call [old_int] с предварительным сохранением регистра статуса в стеке с помощью команды pushf, а если в конце, то можно использовать вызов jmp [old_int], который заменяет команду iret. В данном примере old_int переменная типа double word, в которой хранится адрес старого обработчика.

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

Пример обработчика прерывания:

proc NewInt

push AX

push DS

sti

mov AX , DATA_SEG ; Настроить сегмент данных

mov DS , AX

pushf ; Вызвать старый обработчик

call [old _int]

mov AL , 20h ; Послать команду окончания обработки (опционально)

out 20h, AL

pop DS

pop AX

iret

endp NewInt