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

Замена обработчика прерываний

Хотя прямое изменение таблицы векторов прерываний и кажется достаточно удобным, все-таки это не лучший подход к установке обработчика прерывания, и пользоваться им следует только в случаях крайней необходимости, например внутри обработчиков прерываний. Для обычных программ DOS предоставляет две системные функции: 25h и 35h — установить и считать адрес обработчика прерывания, которые и рекомендуются к использованию в обычных условиях:

; скопировать адрес предыдущего обработчика в переменную old_handler

mov ax,3587h ; АН = 35h, AL = номер прерывания

int 21h ; функция DOS: считать

; адрес обработчика прерывания

mov word ptr old_handler,bx ; возвратить

; смещение в ВХ

mov word ptr old_handler+2,es ; и сегментный

; адрес в ES,

; установить наш обработчик

mov ax,2587h ; АН = 25h, AL = номер прерывания

mov dx,seg int_handler ; сегментный адрес

mov ds,dx ; в DS

mov dx,offset int_handler ; смещение в DX

int 21h ; функция DOS: установить

; обработчик

; (не забывайте, что ES изменился после вызова функции 35h!)

[...]

; восстановить предыдущий обработчик

lds dx,old_handler ; сегментный адрес в DS и смещение в DX

mov ax,2587h ; АН = 25h, AL = номер прерывания

int 21h ; установить обработчик

Программы, остающиеся в памяти, после того как управление возвращается в DOS, называются резидентными. Превратить программу в резидентную просто — достаточно вызвать специальную системную функцию DOS.

Функция DOS 31h: Оставить программу резидентной

Ввод: АН = 31h AL = код возврата DX = размер резидента в 16-байтных параграфах (больше 06h), считая от начала PSP

Кроме того, существует и иногда используется предыдущая версия этой функции — прерывание 27h:

INT 27h: Оставить программу резидентной

Ввод: АН = 27h DX = адрес последнего байта программы (считая от начала PSP) + 1

Эта функция не может оставлять резидентными программы размером больше 64 Кб, но многие программы, написанные на ассемблере, соответствуют этому условию. Так как резидентные программы уменьшают объем основной памяти, их всегда пишут на ассемблере и оптимизируют для достижения минимального размера.

Никогда не известно, по каким адресам в памяти оказываются загруженные в разное время резидентные программы, поэтому единственным несложным способом получения управления является механизм программных и аппаратных прерываний. Принято разделять резидентные программы на активные и пассивные, в зависимости от того, перехватывают ли они прерывания от внешних устройств или получают управление, только если программа специально вызовет команду INT с нужным номером прерывания и параметрами.