
- •1. Рп с вызовом через вектор прерывания Int 60h.................4
- •Резидентные программы
- •1. Установка резидентной программы
- •2. Резидентный обработчик прерываний от клавиатуры с подключением до системного обработчика.
- •3. Резидентный обработчик прерываний от клавиатуры
- •4. Резидентная программа
- •5. Выгрузка рп с помощью ее вызова
- •6. Общая программа загрузки и выгрузки рп
- •7. Обработка опций
- •8. Создание диалоговой среды
- •9. Загрузка рп в верхнюю память
- •10. Действия,выполняемые рп
- •Задание на курсовую работу
3. Резидентный обработчик прерываний от клавиатуры
с подключением после системного обработчика
Здесь, сразу после входа в резидентную программу, нужно командой
CALL вызвать системный обработчик по старому адресу вектора
перехваченного прерывания для обработки кода нажатой клавиши с
возвратом в резидентную программу.
Затем прочитать из буфера клавиатуры код клавиши, проанализировать
его, выполнить наш обработчик прерывания и самостоятельно выйти в
DOS.
Пример 3
Создадим резидентную программу с вызовом по комбинации клавиш
Ctrl+Z с полным кодом (скан-код + ASCII-код) в буфере клавиатуры
равным 2C1A.
При вызове программа выводит цветной символ в последнюю
позицию экрана и меняет цвет символа при каждом новом вызове.
Seg1 SEGMENT
ASSUME SS:Seg1,DS:Seg1,CS:Seg1,ES:Seg1
ORG 100h ;Начало программы с 0100h
Pr: JMP M1 ;Пропускаем резидентную часть
;--------------------- Резидентная часть
old_09 dd 0 ;Старый адрес Int 09h
sym1 dw 421Eh ;1-й выводимый символ
sym2 dw 241Eh ;2-й выводимый символ
M2: pushF ;Регистр флагов - в стек
call CS:old_09 ;Вызов системного обр. прер. 09h
push AX ;Сохраним те регистры, содержимое
push BX ;которых меняется в программе
push ES ;
mov AX,40h ;Занесение сегментного адреса
mov ES,AX ;буфера клавиатуры в рег.ES
mov BX,ES:[1Ah] ;Адрес головы буфера клавиатуры
mov AX,ES:[BX] ;Чтение кода нажатой клавиши
cmp AX,2C1Ah ;Сравнение его с Ctrl+Z
jnz M3 ;Переход на выход, если не Ctrl+Z
mov AX,0B800h ;В рег.ES засылаем сегментный
mov ES,AX ;адрес буфера экрана B800
mov AX,CS:sym1 ;¬
xchg AX,CS:sym2 ;¦Oбмен местами sym1 - sym2
mov CS:sym1,AX ;-
mov ES:3998,AX ;Вывод в посл.поз.экрана 3998
M3: pop ES ;Восстановим содержимое
pop BX ;регистров ES, BX и AX
pop AX ;
iret ;Выход в DOS
M1: ;---------------------- ;Инициирующая часть
mov AX,3509h ;Получить в ES:BX старый адрес
INT 21h ;обработчика прерывания int 09h
mov word ptr CS:old_09,BX ;и запомнить его
mov word ptr CS:old_09+2,ES ;в ячейке old_09
mov AX,2509h ;Установка нового адреса <адр.M2>
lea DX,M2 ;обработчика прерывания int 09h
INT 21h ; -------
mov AH,09h ;Вывод строки:
lea DX,x ;'Резидентный обработчик загружен$'
INT 21h ; -------
mov AX,3100h ;Завершить и оставить резидентной
mov DX,(M1-Pr+10Fh)/16 ;часть размером (M1-Pr+10Fh)/16
INT 21h ; -------
x db 'Резидентный обработчик загружен$'
Seg1 ENDS ;Конец сегмента
END Pr ;Полный конец программы Pr
Здесь при выходе в DOS не нужно засылать признаки окончания
обработки кода клавиши, так как эти признаки уже занесены при
выполнении программы системного обработчика прерываний 09h.
Поскольку прерывание уже обработано, мы пользуемся для анализа
кода клавиши содержимым буфера клавиатуры, хотя ничто не запрещает
испoльзовать для этой цели и регистр с адресом 60h, как в предыдущем
примере.
Команда 'pushf' необходима потому, что выход из системного
обработчика прерываний производится по IRET (извлекая из стека 3
слова), а вызываем мы его командой CALL (помещая в стек 2 слова).