Глава 1. Системные ресурсы.

Раздел 3. Управление программами.

1.3.4 Сохранение программы в памяти после завершения.

Программы, оставленные резидентными в памяти, могут служить в качестве утилит для других программ. Обычно такие программы вызываются через неиспользуемый вектор прерывания. MS DOS рассматривает такие программы как часть операционной системы, защищая их от наложения других программ, которые будут загружены впоследствии. Резидентные программы обычно пишутся в форме COM, что обсуждается в пункте {1.3.6}. Программы, написанные в форме EXE оставить резидентными в памяти немного труднее.

Завершение программы прерыванием 27H оставляет ее резидентной в памяти. CS должен указывать на начало PSP для того, чтобы эта функция работала правильно. В программах COM, CS сразу устанавливается соответствующим образом, поэтому надо просто завершить программу прерыванием 27H. В программах EXE , CS первоначально указывает на первый байт, следующий за PSP (т.е. 100H). При нормальном завершении EXE программы последняя инструкция RET выталкивает из стека первые положенные туда значения: PUSH DX / MOV AX,0 / PUSH AX. Поскольку DS первоначально указывает на начало PSP, то при получении этих значений из стека счетчик команд указывает на смещение 0 в PSP, где при инициализации записывается инструкция INT 20H. Поэтому INT 20H выполняется, а это стандартная функция для завершения программы и передачи управления в DOS. Hа рис. 1-5 показан этот процесс. Чтобы заставить прерывание 27H работать в EXE программе надо поместить 27H во второй байт PSP (первый содержит машинный код инструкции INT), а затем завершить программу обычным RET. Для обоих типов файлов прежде чем выполнить прерывание 27H, DX должен содержать смещение конца программы, отсчитываемое от начала PSP.

Средний уровень.

Вектор прерывания устанавливается с помощью функции 25H прерывания 21H, как показано в {1.2.3} (здесь используется вектор 70H). Позаботьтесь, чтобы процедура оканчивалась IRET. Kроме самой процедуры, устанавливаемая программа не должна делать ничего, кроме инициализации вектора прерывания, присвоения DX значения смещения конца процедуры и завершения. Для COM файлов просто поместите оператор INT 27H в конец программы. Для EXE файлов поместите этот оператор в первое слово PSP и завершите программу обычным оператором RET. Для того чтобы выполнить процедуру, впоследствии загруженная программа должна вызвать INT 70H.

Приведены примеры для обоих типов файлов (COM и EXE). В обоих установлена метка FINISH для отметки конца процедуры прерывания (напоминаем, что знак $ дает значение счетчика команд в этой точке). Для COM файлов FINISH дает смещение от начала PSP, как и требуется для прерывания 27H. Для EXE файлов смещение отсчитывается от первого байта, следующего за PSP, поэтому к нему необходимо прибавить 100H, чтобы пересчитать на начало PSP. Заметим, что поместив процедуру в начало программы, мы можем исключить установочную часть кода из резидентной порции. Другой возможный фокус состоит в использовании инструкции MOVSB для пересылки кода процедуры вниз в неиспользуемую часть PSP, начиная со смещения 60H, что освобождает 160 байт памяти.

Случай файла COM:
;---здесь процедура прерывания
BEGIN: JMP SHORT SET_UP ;переход на установку
ROUTINE PROC FAR
PUSH DS ;сохранение регистров
.
(процедура)
.
POP DS ;восстановление регистров
IRET ;возврат из прерывания
FINISH EQU $ ;отметка конца процедуры
ROUTINE ENDP
;---установка вектора прерывания
SET_UP: MOV DX,OFFSET ROUTINE ;смещение процедуры в DX
MOV AL,70H ;номер вектора прерывания
MOV AH,25H ;функция установки вектора
INT 21H ;устанавливаем вектор
;---завершение программы, оставляя резидентной
LEA DX,FINISH ;определяем треб. смещение
INT 27H ;завершение

Случай файла EXE:
;---здесь резидентная процедура
JMP SHORT SET_UP ;переход на установку
ROUTINE PROC FAR
PUSH DS ;сохранение регистров
.
(процедура)
.
POP DS ;восстановление регистров
IRET ;возврат из прерывания
FINISH EQU $ ;отметка конца процедуры
ROUTINE ENDP
;---установка вектора прерывания
SET_UP: MOV DX,OFFSET ROUTINE ;смещение процедуры в DX
MOV AX,SEG ROUTINE ;сегмент процедуры в DS
MOV DS,AX ;
MOV AL,70H ;номер вектора прерывания
MOV AH,25H ;функция установки вектора
INT 21H ;установка вектора
;---завершение программы
MOV DX,FINISH+100H ;вычисляем смещение конца
MOV BYTE PTR ES:1,27H ;посылаем 27H в PSP
RET ;завершаем процедуру

Функция 31H прерывания 21H работает аналогично, за исключением того, что в DX должно содержаться число 16-байтных параграфов, требуемых процедуре (вычисление размера процедуры, начиная от начала PSP - см. в примере {1.3.1}). Преимуществом этой функции является то, что она передает родительской программе код выхода, дающий информацию о статусе процедуры. Родительская программа получает этот код с помощью функции 4DH прерывания 21H. Kоды выхода обсуждаются в {7.2.5}.


<~-1.3.3 Использование команд интерфейса с пользователем из программы.
Содержание
1.3.5 Загрузка и запуск программных оверлеев.-~>

Сайт управляется системой uCoz