|
|
|
|
Захват векторов прерываний
В какой-либо точке секции своей инициализации TSR может объявить свою собственную ISR int 2Fh, чтобы впоследствии при активациях программы можно
было бы локализовать ее резидентную часть. Для этого TSR может также потребоваться модификация других входов IVT. Прерывания int 25h (чтение с диска по
абсолютным адресам) и int 26h (запись на диск по абсолютным адресам) затрудняют измене ние стека. Благодаря своей природе, прерывание int 13h (нижний
уровень в/в диска) не может быть прервано. Представьте себе, что произойдет, если прерывание с кодом int 13h было бы прервано между поиском и передачей.
Если при отработке этого прерывания случится еще одна операция в/в, то первая передача, по всей вероятности, нанесет серьезный ущерб структуре диска.
В связи с этим DOS не подразумевает никаких прерываний во время обслуживания одного из этих запросов. За защиту операционной системы DOS в
подобные моменты ответственность несет программа TSR. Захват этих векторов позволяет TSR управлять активностью диска. Эти ISR должны писаться с
использованием определенных трюков из-за способа использования флажков процессора. Исходная ISR int 13h возвращает результат в регистре флажков; новая
ISR должна возвращать эти результаты быстрее, чем инструкция int 13h занесет их в стек. Исходные ISR int 25h и int 26h добавляют, кроме того, другое
искажение, занося флажки в стек инструкцией INT. Заметим, что новые программы ISR NewInt25 и NewInt26 перед вызовом исход ной подпрограммы не выполняют
инструкцию push, и что все эти ISR используют возврат far далекий. Что необходимо делать при захвате этих прерываний, показано в листинге 4-23.
При захвате прерывания будьте осторожны. Так как вход IVT модифицирован, процессор будет диспетчировать новую ISR, даже если адрес ISR больше не
указывает на правильную программу. Можно ожидать возникновения прерываний и критических ошибок. Если после захвата прерывания возникнет любое из этих
условий, то они могут вызвать завершение программы. Операционная система DOS будет повторно использовать память, занятую Вашей программой и ее ISR.
Так как это происходит, то входы IVT недолго указывают на правильные программы ISR.
----------------------------------------------------------------
П Р Е Д О С Т Е Р Е Ж Е Н И Е
Перед модификацией любого вектора прерывания необходимо
установить свои собственные программы ISR для break и кри-
ческой ошибки.Не пытайтесь восстановить любой из этих век-
торов.При завершении Вашей программы DOS будет фиксировать
входы IVT для этих функций. Если Вы пытаетесь восстановить
адрес критической ошибки, либо адрес прерывания и захвати-
ли другие векторы, то Ваша программа станет уязвимой к
преждевременному завершению.
----------------------------------------------------------------
|
Листинг 4-23. Типовое замещение программ ISR дискового в/в
----------------------------------------------------------------
DiskIO PROC FAR
OldInt13 DD 0 ; здесь программа инициализации
OldInt25 DD 0 ; записывает адреса оригинальных
OldInt26 DD 0 ; int 13h, int 25h и int 26h
BusyFlag DB -1 ; флажок защиты от прерывания
; нереентерабельной программы
DiskIOExit0:
pushf ; сохраняет флажки дискового в/в
dec cs:BusyFlag ; снимает блокировку
popf ; восстанавливает флажки диск.в/в
ret 2 ; возврат с удалением флажков, по-
; мещенных при прерывании
DiskIOExit1:
pushf ; сохраняет флажки дискового в/в
dec cs:BusyFlag ; снимает блокировку
popf ; восстанавливает флажки диск.в/в
ret
NewInt13:
inc cs:BusyFlag ; снимает блокировку
pushf ; имитирует прерывание
call cs:OldInt13 ; диспетчирование реальной прог-
; раммой
jmp SHORT DiskIOExit0
; переход к общему выходу
NewInt25: inc cs:BusyFlag ; снимает блокировку
call cs:OldInt25 ; диспетчирование реальной прог-
; раммой
jmp SHORT DiskIOExit1
; переход к общему выходу
NewInt26: inc cs:BusyFlag ; снимает блокировку
call cs:OldInt26 ; диспетчирование реальной прог-
; раммой
jmp SHORT DiskIOExit1
; переход к общему выходу
DiskIO ENDP
----------------------------------------------------------------
|
|
|