Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция № 7 Структура MS DOS.ppt
Скачиваний:
22
Добавлен:
07.08.2024
Размер:
1.12 Mб
Скачать

Выгрузка резидентной программы из памяти

Если же программа все-таки выгружается, то это можно сделать с помощью уже рассмотренного выше мультиплексного прерывания 2Fh. Если встроенный в резидентную программу обработчик этого прерывания, анализируя номер­ подфункции (содержимое регистра AL), обнаруживает, что этот номер соответствует­ команде выгрузки, он реализует все действия, необходимые для выгрузки программы­ из памяти.

Вызов прерывания 2Fh, реализующий выгрузку конкретной резидентной программы, можно выполнить в специально созданной выгружающей программе. Практически всегда в качестве выгружающей используют саму резидентную программу, точнее, ее вторую копию, которая, если ее запустить в определенным режиме, не только не пытается остаться в памяти, но, наоборот, выгружает из памяти свою первую копию.

Выгрузка резидентной программы из памяти

Пусть, подфункция 00h прерывания 2Fh в приведенном ниже примере служит для проверки на наличие в памяти, а подфункция­ 01h - для выгрузки.

Выгрузка резидентной программы из памяти

Резидентный обработчик прерывания 2Fh прежде всего проверяет номер функции, поступивший в регистре АН. Если этот номер отличается от C8h, управление передается­ следующему обработчику по цепочке.

Далее анализируется содержимое регистра AL. Если AL=00h, осуществляется переход на метку iamhere, где в регистр AL засыла­ ется код FFh наличия в памяти первого экземпляра данной программы, после чего командой­ iret управление возвращается в вызывающую программу.

Если AL=01h осуществляется­ переход на метку uninst для выполнения действий по выгрузке программы­. При любом другом номере подфункции управление передается следующему обработчику по цепочке.

Выгрузка резидентной программы из памяти

По метке uninst осуществляется сохранение используемых далее регистров, и функцией DOS 25h восстанавливается­ из ячеек old_08h и old_2Fh исходное содержимое соответствующих векторов.

Далее из ячейки со смещением 2Ch относительно начала PSP в ES загружается адрес окружения программы. При загрузке программы MS DOS, кроме программных сегментов, создает для нее еще и сегмент окружения. Сегмент окружения содержит ASCIIZ- строки, задающие значения некоторых глобальных переменных, эти значения могут устанавливаться командой MS DOS SET, они доступны командным файлам и - через PSP – программам.

Сегментный адрес освобождаемого блока памяти - единственный­ параметр, требуемый для выполнения функции DOS 49h (размер освобождаемого блока DOS известен, он хранится в

Выгрузка резидентной программы из памяти

Далее освобождается­ блок памяти с самой программой. Сегментный адрес этого блока (адрес PSP) находится, естественно, в CS. Наконец, командой iret управление передастся в программу,­ вызвавшую прерывание 2Fh.

Для того,­ чтобы удалить из памяти резидентную программу, достаточно в какой-то программе­ вызвать прерывание 2Fh с функцией, присвоенной нашей программе, и подфункцией­ выгрузки 01h. Проще всего создать для этого специальную выгружающую программу:

Выгрузка резидентной программы из памяти

Любопытно, что в выгружающей программе не указывается имя выгружаемой. Выгружается та резидентная программа, которой при ее разработке была назначена функция C8h мультиплексного прерывания.

Очевидно, что методика выгрузки резидентной программы с помощью специально предназначенной для этого выгружающей программы довольно неуклюжа. Для каждой­ резидентной программы придется создавать выгружающую. Гораздо изящнее использовать в качестве выгружающей саму резидентную программу. Обычно в ней предусматривают анализ запускающей программу командной строки так, чтобы ввод с клавиатуры имени программы загружал эту программу в память, оставляя ее резидентной,­ а ввод имени программы с параметром off приводил к выгрузке программы.

Выгрузка резидентной программы из памяти

Последний шаг в выгрузке программы — освобождение памяти — можно выполнить вручную, как в примере выше, вызывая функцию DOS 49h на каждый блок памяти, который программа выделяла через функцию 48h, на блок с окружением DOS, если он не освобождался при загрузке, и наконец, на саму программу. Однако есть способ заставить DOS сделать все это (а также закрыть открытые файлы и вернуть код возврата) автоматически, вызвав функцию 4Ch, объявив резидент текущим процессом.

Выгрузка резидентной программы из памяти

Выгрузка резидентной программы из памяти

Здесь использован еще две недокументированных функции прерывания 21Н:

Функция 50h: установить сегмент для нового PSP Вход: AH = 50h

BX = адрес сегмента нового PSP Возврат: ничего

Функция 51h(81): Считать текущий сегмент PSP Вход: AH = 51h

Возврат: BX = адрес сегмента текущего PSP