Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МЕТ_ОРГ_1.doc
Скачиваний:
29
Добавлен:
18.11.2019
Размер:
1.27 Mб
Скачать
    1. Примеры резидентных программ

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

Программа № 01

; Необходимо перехватить 21h прерывание, тем самым контролировать кто и что делает с ним.

CSEG segment

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG

org 100h

Start:

;Переходим на метку инициализации. Нам нужно будет перехватить прерывание 21h, а также оставить программу резидентной в памяти

jmp Init

; Ниже идет, собственно, обработчик 21h прерывания (он будет резидентный). После того, как программа выйдет, процедура Int_21h_proc останется в памяти и будет контролировать функцию 09 прерывания 21h. Int_21h_proc proc

Pushf ;сохраним в стеке регистр флагов

cmp ah,9 ;проверим: это функция 09h?

je Ok_09

popf ;восстановим регистр флагов

jmp dword ptr cs:[Int_21h_vect] ;Если нет, прейдем на оригинальный обработчик прерывания 21h

Ok_09: push ds ;Сохраним регистры

push dx

push cs ;Адрес строки должен быть DS:DX

pop ds

mov dx, offset My_string

pushf

call dword ptr cs:[Int_21h_vect] ;Вывели нашу строку вместо той, которую надо было

pop dx ;восстановим использованные регистры

pop ds

popf

iret ;продолжим работу (выйдем из прерывания)

Int_21h_vect dd ? ;переменная для хранения оригинального адреса обработчика 21h

My_string db 'Моя строка!$'

int_21h_proc endp

;Со следующей метки нашей программы уже не будет в памяти (это нерезидентная часть). Она затрется сразу после выхода.

Init:

;установим адрес нашего обработчика на 21h прерывание. Это позволяет сделать функция 25h прерывания 21h. Но прежде нам нужно запомнить оригинальный адрес этого прерывания. Для этого используется функция 35h прерывания 21h:

mov ah,35h ;AH содержит номер функции

mov al,21h ;AL указывает номер прерывания, адрес (или вектор) которого нужно получить

int 21h ;тепрь в ES:BX адрес (вектор) 21h прерывания (ES - сегмент, BX - смещение)

mov word ptr Int_21h_vect,bx

mov word ptr Int_21h_vect+2, es ;итак, адрес сохранили. Теперь перехватываем прерывание:

mov ax,2521h

mov dx,offset Int_21h_proc ;DX должен указывать на наш обработчик (т.е. Int_21h_proc)

int 21h

;Все! Теперь, если какая-либо программа вызовет 21h, то вначале компьютер попадет на наш обработчик (Int_21h_proc).

mov dx,offset Init

int 27h

; прерывание 27h выходит в DOS (как 20h), при этом оставив нашу программу резидентной. DX должен указывать на последний байт, остающийся в памяти (это как раз метка Init).

CSEG ends

end Start

Для примера создадим простейшую программу, которая будет выводить на экран некоторую строку путем вызова 09 функции 21h прерывания. Например, так:

Программа №02

CSEG segment

assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG

org 100h

Begin:

mov ah,9

mov dx,offset String

int 21h

int 20h

String db 'My string.$'

end Begin

CSEG ends

Запускаем вначале Программу № 01, затем запускайте Программу N 02.