|
|
|
|
Определение безопасности повторной активации
Невозможно предсказать, когда произойдет запрос на повторную активацию TSR. Секции DOS не являются повторно входимыми, поэтому и TSR не всегда
может повторно активироваться при выдаче запроса повторной активации. Детально эта проблема обсуждается в разделе "Архитектура DOS". Необходимо с
уважением относиться к этим ограничениям, иначе Ваша программа, несомненно, разрушит систему и, даже, возможно, разрушит диск.
Минимальный объем проверок, который должна выполнять Ваша TSR, приведен в листинге 4-27. Эта программа предназначена для выполнения с
запрещением прерываний. Когда процессор отвечает на прерывание, он запрещает прерывания. До тех пор, пока программа обслуживания прерывания не
разрешит прерывания перед вызовом DOSSafeCheck, Вы не должны неявным образом манипулировать флажком прерывания.
Эта программа начинается с увеличения значения того же самого флажка BusyFlag (флажок "занято"), используемого новой подпрограммой дискового в/в
(листинг 4-23 "Типовое замещение программ ISR дискового в/в"). Этот флажок имеет начальное значение -1. Если инструкция INC в DOSSafeCheck имеет нулевой
результат, то продолжение выполнения безопасно. Ненулевой результат означает, что выполняется одна или более дисковых операций (в конечном счете,
прерывание int 13h выполняется как результат прерываний int 25h и int 26h), или незавершен предыдущий вызов TSR. Так как переключение стека выполняется
программой повторной активации, то TSR не является повторно входимой. (Позднее последовательность повторной активации будет описана более подробно).
Затем эта программа проверяет флажки критической секции и критического прерывания. Заметим, что необходимо проверять оба флажка. Перед началом
обработки критической ошибки драйвер критической ошибки DOS уменьшает значение флажка критической секции и увеличивает значение флажка критической
ошибки. Побочным эффектом вызова этой подпрограммы является то, что она предохраняет TSR от повторного входа. Перед тем, как TSR переключится в фоновый
раздел, она должна уменьшить значение флажка "занято" (BusyFlag).
Листинг 4-27. Определение "безопасности" повторной активации
----------------------------------------------------------------
BusyFlag: DB -1 ; флажок "занято"
CSectFlg DW 0,0 ; здесь при инициализации запоми-
; нается адрес флажка критической
; секции
CErrFlg DW 0,0 ; здесь при инициализации запоми-
; нается адрес флажка критической
; ошибки
DOSSafe PROC NEAR
DOSNotSafe:
stc ;;; индикация, что "небезопасно"
ret ;;; и возврат
DOSSafeCheck:
inc cs:BusyFlag ;;; попытка снять блокировку
jg DOSNotSafe ;;; если больше -- то некоторые
;;; уже имеют блокировку
pushr ;;; сохранение, т.к. мы можем по-
;;; лучить при INDosFlag
lds si,DWORD PTR cs:CSectFlg ;;; ds:si <== адрес
;;; флажка критической секции
lodsb ;;; al <== значение флажка крити-
;;; ческой секции
lds si,DWORD PTR cs:CErrFlg ;;; ds:si <== адрес
;;; флажка критической ошибки
or al,BYTE PTR [si] ;;; вычисление ненулевого
;;; флажка критической ошибки
popr
jnz DOSNotSafe ;;; если не 0, то либо критичес-
;;; кая ошибка, либо int 21
clc ;;; индикация, что "безопасно"
ret ;;; и возврат
DOSSafe ENDP
----------------------------------------------------------------
|
|
|