|
|
|
|
Организация "ловушек" break и критических ошибок
Следующий шаг в последовательности активации связан с изменением информации состояния, которую DOS записала относительно текущей программы. В этой
точке Ваша TSR теперь становится текущей программой. Так как критические ошибки и критические break могут завершить текущую программу, необходимо быть
уверенным в том, что Вы получили шанс вернуться обратно и нашли способ как это сделать. Установка своих собственных драйверов критической ошибки и
break позволяет TSR быть аккуратной в таких случаях и обходиться с ними безопасным способом.
В связи с отсутствием способа определения из программы ISR текущей программы переднего плана, установка драйверов критической ошибки и break
является искусным приемом программирования. Если для манипуляции входом IVT используется int 21, то существует определенный риск получения ошибки
break . Самым безопасным способом является способ манипуляции входами IVT непосредственно. Заметим, что необходимо запретить break , пока производится
изменение входов таблицы. Хотя это и не кажется очевидным, другие программы могут прервать Вашу программу в середине выполнения изменений, и могут
модифицировать входы IVT, с которыми Вы работаете. Как выполнить эту задачу, показывает листинг 4-28.
Действия, которые будут выполняться во вновь установленных драйверах break и критической ошибки, зависят от TSR. Они могут быть проигнорированы,
но, обычно, программа при возникновении критической ошибки должна выполнить какие-либо действия. Если TSR может иметь дело со сбойными запросами int
21h (практически, необходимо проверять результаты выполнения каждого запроса и быть готовым иметь дело с ошибками), то простейшим способом обработки
является отказ от вызова. В то же время имеются другие способы обработки. Например, если произошел сбой диска в связи с тем, что была открыта дверца
накопителя, то необходимо напечатать сообщение и повторить операцию.
Листинг 4-28. "Ловушка" критических ошибок и break из ISR
----------------------------------------------------------------
IVT SEGMENT AT 00h ; отметить абсолютный адрес
ORG 23h*4 ; мы не заботимся относительно
; 0 - 22h
IVT23 DW 0,0 ; входы ссылок для int 23h и
IVT24 DW 0,0 ; int 24h
IVT ENDS
_text SEGMENT BYTE PUBLIC 'code'
OldInt23 DW 0,0 ; здесь мы будем сохранять адре-
OldInt24 DW 0,0 ; са критической ошибки и преры-
; вания
ASSUME ds:_text
BKGNewErrHndlr PROC NEAR
pushr ; сохранение всех изменяе-
; мых регистров
cld ; вывод флажка направления в из-
; вестное состояние для movsw и
; stosw
mov ax,cs ; es указывает на сегмент, содер-
mov es,ax ; жащий OldInt23
xor ax,ax ; ds указывает
mov ds,ax ; на IVT
ASSUME ds:IVT,es:_text ; сообщить MASM, что ожидание
mov si,OFFSET IVT23 ; установить копию IVT
mov di,OFFSET OldInt23 ; входы с movsw
mov cx,4 ; каждый вход 2 слова
cli ; В А Ж Н О !!!
rep movsw ;;; копирование текущих входов
;;; ivt
mov es,ax ;;; es теперь указывает на IVT
ASSUME es:IVT ;;; сообщить MASM об изменении
mov ax,OFFSET NewInt23 ;;; ввод новых значений
stosw ;;; в IVT
mov ax,cs
stosw
mov ax,OFFSET NewInt24
stosw
mov ax,cs
stosw
sti
popr
ASSUME ds:_text
ret
BKGNewErrHndlr ENDP
NewInt23 PROC FAR ; новый обработчик break
iret ; игнорирование break
NewInt23 ENDP
NewInt24 PROC NEAR ; новый обработчик критической
; ошибки
iret ; вероятно будут выполнены ка-
; кие-либо действия относительно
; ошибки (может быть отказ вызова)
NewInt24 ENDP
_text ENDS
----------------------------------------------------------------
|
|
|