- •1. Рп с вызовом через вектор прерывания Int 60h.................4
- •Резидентные программы
- •1. Установка резидентной программы
- •2. Резидентный обработчик прерываний от клавиатуры с подключением до системного обработчика.
- •3. Резидентный обработчик прерываний от клавиатуры
- •4. Резидентная программа
- •5. Выгрузка рп с помощью ее вызова
- •6. Общая программа загрузки и выгрузки рп
- •7. Обработка опций
- •8. Создание диалоговой среды
- •9. Загрузка рп в верхнюю память
- •10. Действия,выполняемые рп
- •Задание на курсовую работу
6. Общая программа загрузки и выгрузки рп
Конечно, создавать специальную программу для выгрузки не слишком
изящный способ. Гораздо удобнее использовать одну и ту же программу,
как для загрузки так и для выгрузки резидентной программы. Для этого
в инициирующей части программы сделаем проверку:
- если программа запущена без параметров в виде
res.com или res
выполняется загрузка резидентной программы;
- если программа запущена с параметром в виде
res.com оff или res off
выполняется выгрузка резидентной программы из памяти.
Такую проверку можно сделать, получив из PSP:80h число символов в
командной строке после имени команды.
Пример 6
Создадим резидентную программу, полностью соответствующую программе
примера 5, но вместо отдельной программы выгрузки, включим ее функции в
инициирующую часть. Приведем здесь только инициирующую часть программы,
так как резидентная часть осталась без изменений.
M1: ;---------------------- ;Инициирующая часть
mov AL,CS:80h ;Чтение из PSP:80h кол-ва символов
cmp AL,0 ;Если их нет, то нужна загрузка РП
jz M7 ;иначе выгрузка РП
;---------------------- ;Вызов выгрузки РП
mov AH,0C8h ;Вызов INT 2Fh с функцией C8h
mov AL,01 ;и подфункцией 01h
INT 2Fh ; -------
mov AX,4C01h ;Завершить обычным способом
INT 21h
M7: ;---------------------- ;Вызов загрузки РП
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 ;Завершить и оставить pезидентной
mov DX,(M1-Pr+10Fh)/16 ;часть размером (M1-Pr+10Fh)/16
INT 21h ; -------
x db 'Резидентный обработчик загружен$'
Seg1 ENDS ;Конец сегмента
END Pr ;Полный конец программы Pr
7. Обработка опций
В предыдущем примере мы только анализировали, введены ли
дополнительные символы в командной строке после имени команды или их
нет. В зависимости от этого выполнялась загрузка или выгрузка
резидентной программы. Причем, достаточно было даже одного пробела,
чтобы выполнялась вторая функция. Это не слишком удобно.
Во избежание ошибок лучше было бы указывать опции, например:
res /z - загрузить в память резидентную программу
res /u - выгрузить из памяти резидентную программу
Рассмотрим обработку таких опций. Напомню, что все символы вводимые при
запуске программы из командной строки, заносятся в буфер командной
строки PSP, начиная с адреса смещения 0080h. Например, при вводе команды
res /z в буфер занесется:
0080) 03 20 2F 7A 0D
¦ ¦ / z L-- Enter
¦ L-- пробел
L-- число символов после 'res' в 16 с/с
Причем, все пробелы тоже заносятся в буфер, и символ '/' не обязательно
будет находиться по адресу 0082h, поэтому в программе анализа сначала
найдем этот символ, а затем проанализируем, что стоит за ним.
Пример 7
Напишем фрагмент программы, который анализирует приведенные выше
опции. Этот фрагмент можно вставить вместо первых восьми команд
инициирующей части примера 6 (от метки M1 до метки M7).
M1: ;---------------------- ;Инициирующая часть
mov CL,ES:80h ;Чтение из PSP:80h кол-ва символов
cmp CL,0 ;Если их нет, то вывод сообщения:
jz M9 ;'Ошибка в указании опций'
mov CH,0 ;Теперь кол. символов в рег.CX
mov AL,'/' ;Поиск символа '/'
mov DI,81h ;начиная с PSP:81h
repnz scasb ;Результат: DI=адр.символа за '/'
cmp byte ptr [DI],'z' ;Если найденный код='z', то
jz M7 ;переход к загрузке РП
cmp byte ptr [DI],'u' ;Если найденный код='u', то
jz M8 ;переход к выгрузке РП
M9: mov AH,09h ;Вывод строки:
lea DX,x2 ;'Ошибка в указании опций'
INT 21h ; -------
mov AX,4C01h ;Завершить обычным способом
INT 21h
x2 db 'Ошибка в указании опций $'
M8: ;---------------------- ;Вызов выгрузки РП
mov AH,0C8h ;Вызов INT 2Fh с функцией C8h
mov AL,01 ;и подфункцией 01h
INT 2Fh ; -------
mov AH,09h ;Вывод строки:
lea DX,x1 ;'Резидентная программа удалена '
INT 21h ; -------
mov AX,4C01h ;Завершить обычным способом
INT 21h
x1 db 'Резидентная программа удалена $'
M7: ;---------------------- ;Вызов загрузки РП
