Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
19
Добавлен:
20.06.2014
Размер:
143.87 Кб
Скачать

Взаимодействие элементов резидентной программы.

Любая резидентная программа имеет по крайней мере две точки входа. При

запуске с клавиатуры программы типа.СОМ управление всегда передается на

первый байт после PSP (IP=100h). Поэтому практически всегда первой командой

резидентной программы является команда jmp, передающая управление на начало

секции инициализации.

После отработки функции DOS 31h программа остается в памяти в пассивном

состоянии. Для того, чтобы активизировать резидентную программу, ей надо

как-то передать управление. Вызвать к жизни резидентную программу можно

разными способами, но наиболее употребительным является механизм аппаратных

или программных прерываний. В этом случае в процессе инициализации необходимо

заполнить соответствующий вектор адресом точки входа в программу. Адрес образует вторую точку входа в программу, через которую осуществляется ее активизация. Очевидно, что резидентная секция программы должна заканчиваться командой выхода из прерывания iret.

Рис.1 элементы резидентной программы и их взаимодействие

PSP

main proc

jmp init

Резидентные данные

entry

.

. Резидентные программы

.

main endp

int proc

.

. Секция инициализации

.

mov AH, 31h

int 21h

init endp

end main


Резидентная часть программы

Часть программы, отбрасываемая после установки в память

После того, как программа загружена и осталась

резидентной, удалить ее из памяти уже нельзя никакими силами. Чтобы привести компьютер в обычное состояние, его придется перезагрузить. В DOS не предусмотрены средства удаления резидентных программ; резидентная программа должна иметь такие средства внутри себя. Трудность здесь заключается в том, что резидентные программы практически всегда заполняют какие-то векторы прерываний, и перед выгрузкой такой программы из памяти эти векторы следует восстановить, чтобы не нарушить работоспособность системы. Однако никто, кроме самой программы, не знает, какие векторы были разрушены, и что в них было до вмешательства резидентной программы. Поэтому почти невозможно корректно выгрузить резидентную программу без ее активного участия в этом процессе. Включение в резидентную программу средств ее выгрузки (обычно по команде пользователя) требует существенного ее усложнения.

Чтобы выгрузить резидентную программу, необходимо:

- восстановить прежние значения всех перехваченных векторов прерываний;

- освободить блок памяти занимаемый программой;

- освободить блок памяти занимаемый ее окружением.

Для выполнения функции освобождения блоков памяти служит прерывание:

Int 21,49 - освободить блок памяти

ES - сегментный адрес выгружаемого блока памяти

Размер выгружаемого блока памяти определяется чтением данных из

блока MCB внутри самого прерывания Int 21,49.

Восстановить прежние значения всех перехваченных векторов прерываний

можно только внутри собственной программы, так как никто не знает, где

спрятаны старые значения их адресов.

ЗАМЕЧАНИЕ: Корректно выгрузить можно только последнюю резидентную

программу, перехватившую заданное прерывание. В противном случае, все

позже загруженные резидентные программы, вызываемые тем же прерыванием,

останутся в памяти но вызываться не будут.

Текст программы:

Резидентный обработчик прерываний от таймера

SEG1 SEGMENT

ASSUME SS:Seg1, DS:Seg1, CS:Seg1,ES:Seg1

ORG 100h ; Начало программы с 0100h

PROGA: JMP M1 ; Пропускаем резидентную часть

;-------------------------Рез.часть

;Поля данных резидентной секции

old_2F dd 0 ; Старый адрес Int 2Fh

old_1C dd 0 ; Старый адрес Int 1Сh

count db 0 ; Счетчик для понижения частоты

;таймера

M4: CMP AH, 0C8h ;Cвоя функция прерывания 2Fh?

JNZ M5 ;На переход, eсли не своя

CMP AL,01h ;Cвоя подфункция прерывания 2Fh?

JNZ M5 ;На переход, если не своя

;--------------------Нач.выгрузки

;Сохраним те регистры, содержимое

PUSH DS ;которых меняется в программе

PUSH ES

PUSH DX

MOV DX,CS: word ptr old_1C

MOV DS,CS: word ptr old_1C+2

MOV AX,251Ch ;Восстановление старого адреса old_1C

INT 21h ;обработчика прерывания int 1Ch

MOV DX,CS: word ptr old_2F

MOV DS,CS: word ptr old_2F+2

MOV AX,252Fh ;Восстановление старого адреса old_2F

INT 21h ;обработчика прерывания int 2Fh

MOV ES,CS:2Ch ;Занесение из PSP:2Ch адреса

MOV AH,49h ;окружения в рег.ES и выгрузка

INT 21h ;блока окружения

PUSH CS ;Сегментный адрес начала блока

POP ES ;с программой из рег. CS в ES

MOV AH,49h ;Выгрузка блока с резидентной

INT 21h ;программой

POP DX ;Восстановим содержимое

POP ES ;регистров DS, ES и DX

POP DS

;-------------------Конец выгрузки

IRET ;Возврат в вызвавшую программу

M5: JMP CS:old_2F ;Переход к 'чужой' резидентной

;программе раньше нас перехватившей

;прерывание INT 2Fh

M2: PUSH AX ;-----------Нач. основной РП

PUSH BX ;Сохраним используемые в ней

PUSH CX ; регистры

PUSH ES

INC CS:COUNT ;Инкремент счетчика

TEST byte ptr CS:count,3Fh ;Пересчет на 64

JNZ M3 ;Если не 64-е прерывание - на выход

MOV AX,0B800h ;Настроим ES

MOV ES,AX ;на видеобуфер

;----------------------

MOV AL,84h ;Занесение адреса часов

OUT 70h,AL ;в порт 70h

IN AL,71h ;Чтение числа из порта 71h

MOV BX,00 ;Номер позиции на экране для вывода

CALL P1 ;Вывод 2-х цифр из AL на экран

MOV AL,82h ;Занесение адреса минут

OUT 70h,AL ;в порт 70h

IN AL,71h ;Чтение месяца из порта 71h

MOV BX,06 ;Номер позиции на экране для вывода

CALL P1 ;Вывод 2-х цифр из AL на экран

MOV AL,80h ;Занесение адреса секунд

OUT 70h,AL ;в порт 70h

IN AL,71h ;Чтение года из порта 71h

MOV BX,12 ;Номер позиции на экране для вывода

CALL P1 ;Вывод 2-х цифр из AL на экран

JMP M3

P1 PROC ;---------------Процедура вывода 2-х цифр из AL на экран

PUSH CX ;Сохраним те регистры, содержимое

PUSH AX ;которых меняется в программе

MOV CL,4 ;Число сдвигов

SHR AL,CL ;Сдвиг AL вправо 4 р

CALL P2 ;Перевод цифры из AL в символ

MOV ES:[BX+3980],AX ;Вывод старшей цифры

POP AX ;Восстановим AX

CALL P2 ;Перевод цифры из AL в символ

MOV ES:[BX+3982],AX ;Вывод младшей цифры

MOV AX,0E3Ah ;Вывод символа ':'

MOV ES:[BX+3984],AX

POP CX ;Восстановим CX

RET ;Выход из процедуры вывода

P1 ENDP ;Конец процедуры вывода

P2 PROC ;--------------Процедура перевода цифры из AL в символ

AND AL,0Fh ;Выделение мл. полубайта

ADD AL,'0' ;Добавление кода 30h

MOV AH,0Eh ;Байт атрибутов

RET ;Выход из процедуры перевода

P2 ENDP ;Конец процедуры перевода

M3: POP ES ;Восстановим содержимое

POP CX ;регистров ES,CX,BX и AX

POP BX

POP AX

Соседние файлы в папке Кр и методичка Разработка резидентной программы в MS DOS