Заметим, что call должен быть межсегментным
(дальним) вызовом, потому, что OldInt1c является двойным словом.
Создание горячего ключа
Назначение горячего ключа для TSR налагает некоторые особые
требования на написание программы. Горячий ключ инициирует TSR
- 4-10 -
без передачи сигнала нажатия клавиши программе переднего плана.
При обычном подходе каждое нажатие клавиши перед считыванием его
программой переднего плана анализируется.
Для просмотра ввода в
буфер клавиатуры Вы можете перехватить прерывание 16h или Вы мо-
жете опрашивать буфер клавиатуры, используя прерывания от таймера
(int 1ch), или, наконец, Вы можете управлять содержимым буфера
клавиатуры при перехвате прерывания 9. Довольно часто Вы можете
посчитать полезным назначить горячие ключи, влияющие на состояние
клавиатуры, но не добавляющие символов в буфер клавиатуры.
Каждый
из этих подходов имеет определенные преимущества и проблемы. Вы
имеете возможность решить, какая техника лучше для Вашего прило-
жения.
Подмена Int 16h
Простейшим путем создания горячего ключа является подмена
прерывания int 16h.
Когда старая ISR выполнится, ее команда IRET передаст управ-
ление Вашему коду, который для передачи управления программе вво-
дит собственную команду IRET , которая передает управление прог-
рамме, которая первоначально вызвала прерывание.
DOS обеспечивает два пути для перехвата вектора прерывания.
Для нахождения содержимого специфицированной строки IVT помещает
номер ее прерывания в регистр AL, значение 35h в регистр AH и
выполняет команду 21h. BIOS обеспечивает возвращение содержимого
строки IVT в пару регистров ES:BX.
После записи этого значения, можно модифицировать строку
IVT. В DS:DX загружается адрес новой ISR, в регистре AL задается
номер вектора прерывания, в регистр AH помещается 25h, и выполня-
ется команда 21h. Листинг 4-4 иллюстрирует использование этого
способа подмены прерывания от таймера.
Листинг 4-4. Подмена прерывания от таймера Int 1ch
----------------------------------------------------------------
OldInt1cDD 0
mov ax,351ch ; получение int 1c
int 21h
mov WORD PTR OldInt1c,bx ; сохранение его
mov WORD PTR OldInt1c+2,es; сохранение ds
push ds
mov ax,cs
mov ds,ax
mov ds,OFFSET NewInt1c ; ds:dx <== новая isr
mov ax,251ch ; установить новую isr
int 21h
pop ds ; восстановление ds
; ... ; все, что угодно
NewInt1c PROC FAR
pushf ; моделирование флагов стека
call cs:OldInt1c ; прерывание
; ... ; все, что угодно
iret
NewInt1c ENDP
----------------------------------------------------------------
Специальные действия, включенные в новую ISR, зависят от то-
го, какую строку IVT вы меняете и что вы предпринимаете для вы-
полнения этой замены. Заметим, что новая ISR "сцеплена" со ста-
рой. Эта техника общепринята. Последовательность pushf/call под-
меняет команду INT.