- •1. Рп с вызовом через вектор прерывания Int 60h.................4
- •Резидентные программы
- •1. Установка резидентной программы
- •2. Резидентный обработчик прерываний от клавиатуры с подключением до системного обработчика.
- •3. Резидентный обработчик прерываний от клавиатуры
- •4. Резидентная программа
- •5. Выгрузка рп с помощью ее вызова
- •6. Общая программа загрузки и выгрузки рп
- •7. Обработка опций
- •8. Создание диалоговой среды
- •9. Загрузка рп в верхнюю память
- •10. Действия,выполняемые рп
- •Задание на курсовую работу
4. Резидентная программа
с защитой от повторной установки
Если повторно запускать программу установки резидентной программы,
то она многократно будет устанавливать в памяти свои копии. Это Вы легко
можете проверить на примере программы Norton Commander.
Для защиты от повторной установки, при каждом запуске программы
установки следует проверять - не загружена ли уже наша резидентная
программа? Такую проверку удобнее всего выполнять с помощью
мультиплексного прерывания INT 2Fh, специально предназначенного для
связи с резидентными программами.
При вызове прерывания INT 2Fh в регистр AH заносится номер функции
(00..FFh), а в регистр AL - номер подфункции. Функции 00..BFh
зарезервированы DOS и используются спец. программами. А вот функции
C0h..FFh свободны и могут быть использованы в нашей программе.
Чтобы резидентная программа могла отозваться на вызов INT 2Fh,
в ней должен иметься обработчик этого прерывания. Как правило, все
резидентные программы имеют такие обработчики. Через них осуществляется
связь с резидентной программой: смена режима, получение параметров
и т.п. Задается нужное действие с помощью номера подфункции в рег. AL.
Итак, обработчик прерывания INT 2Fh резидентной программы должен:
- приняв преывание, проверить номер функции в регистре AH и, если
номер не свой, передать управление ранее загруженной резидентной
программе, также использующей прерывание INT 2Fh
JMP CS:old_2f
здесь 'old_2f' - ячейка памяти, где хранится старый адрес вектора
прерывания INT 2Fh.
- если номер функции свой, проверить номер подфункции в регистре AL
и, выполнив необходимые действия (в нашем случае это засылка кода
FFh в регистр AL - признак, что программа уже загружена),
вернуться в вызвавшую программу командой
IRET
Инициирующая часть резидентной программы должна включать в себя:
- вызов прерывания INT 2Fh со своим кодом в регистрах AH и AL;
- проверку кода возврата в регистре AL;
- если AL не равно FFh, то установить резидентную часть программы
и завершить программу прерыванием
E Int 21,31F - завершить и остаться резидентной;
- если AL=FFh, то завершить программу прерыванием
E Int 21,4CF - завершить без резидентной установки
Пример 4
Создадим резидентную программу примера 3, но с защитой от повторной
установки. Приведем здесь только измененное начало резидентной части
программы и полностью - ее инициирующую часть.
;--------------------- Резидентная часть
old_2F dd 0 ;Старый адрес Int 2Fh
old_09 dd 0 ;Старый адрес Int 09h
sym1 dw 421Eh ;1-й выводимый символ
sym2 dw 241Eh ;2-й выводимый символ
M4: cmp AH,0C8h ;Своя функция прерывания 2Fh?
jnz M5 ;На переход, если не своя
cmp AL,00 ;Своя подфункция прерывания 2Fh?
jnz M5 ;На переход, если не своя
mov AL,0FFh ;Занесение признака 'Программа уже
iret ;установлена' и возврат
M5: jmp CS:old_2F ;Переход к 'чужой' резидентной
;программе раньше нас перехватившей
;прерывание INT 2Fh
M2: pushF ;Это начало основной части
call CS:old_09 ;резидентной программы,
push AX ;полностью соответствующей
push BX ;тексту примера 3
.......... ..................
M1: ;---------------------- ;Инициирующая часть
mov AH,0C8h ;Вызов INT 2Fh с функцией C8h
mov AL,00 ;и подфункцией 00h
INT 2Fh ; -------
cmp AL,0FFh ;Вернулась подфункция = FFh?
jz M6 ;Если 'да', то прогр. уже загружена
;---------------------- ;Когда программа еще не загружена
mov AX,352Fh ;Получить в ES:BX старый адрес
INT 21h ;обработчика прерывания int 2Fh
mov word ptr old_2F,BX ;и запомнить его
mov word ptr old_2F+2,ES ;в ячейке old_2F
mov AX,252Fh ;Установка нового адреса <адр.M4>
lea DX,M4 ;обработчика прерывания int 2Fh
INT 21h ; -------
mov AX,3509h ;Получить в ES:BX старый адрес
INT 21h ;обработчика прерывания int 09h
mov word ptr old_09,BX ;и запомнить его
mov word ptr 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 ; -------
M6: ;---------------------- ;Когда программа уже загружена
mov AH,09h ;Вывод строки:
lea DX,x1 ;'Программа уже установлена'
INT 21h ; -------
mov AX,4C01h ;Завершить без установки
INT 21h ;pезидентной программы
x db 'Резидентный обработчик загружен$'
x1 db 'Программа уже установлена$'
Seg1 ENDS ;Конец сегмента
END Pr ;Полный конец программы Pr
