На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 3 / Удаление резидентных подпрограмм из памяти Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Удаление резидентных подпрограмм из памяти

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


Удаление подпрограммы без перезагрузки системы необходимо выполнять с помощью следующих двух шагов:


1. Отключение подпрограммы.


2. Восстановление памяти.


Первый шаг состоит в установке в нулевое состояние вектора, указывающего на подпрограмму. Нулевое состояние для любых потенциальных пользователей означает, что подпрограмма больше недоступна. Если резидентная подпрограмма была расположена на участке памяти ("заплате") для ранее существующего вектора, то вектор должен быть восстановлен так, чтобы он указывал на первоначальную ячейку. Можно написать программу для восстановления вектора, если значение старого вектора хранится где-нибудь в резидентной подпрограмме, и программа восстановления может найти его. Этот процесс сохранения вектора для его последующего восстановления демонстрируется в листингах программ INIT28 (листинг 3-12) и REMOVE (листинг 3-13).


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



          РЕГИСТРЫ                                       ВНЕШНИЙ СЕГМЕНТ
                                                       .----------------.
         AX:4B00 (шест.)<---Функция ВЫПОЛНИТЬ ПРОГРАММУ|       ...      |
                                                       |----------------|
         BX:Указатель на имя файла в ASCIIZ ---------->| имя файла/пути |
                                                       |  нулевой байт  |
         DX:Указатель на блок параметра --------.      |----------------|
                                                |      |       ...      |
          Адрес ENVIRONMENT (СРЕДА) | \/\/\/\/\/\/\/\/ xxxx:0000 .--------
         ---------. |
                   | ASCIIZ string 1 |<----.    |
                   | ASCIIZ string 2 |     |    |
                   |       ...       |     |    |        СЕГМЕНТ ДАННЫХ
                   | ASCIIZ string N |     |    |      .----------------.
                   |  нулевой байт   |     |    |      |        ...     |
                    -----------------      |     ----->|----------------|
                                            -----------|envir.seg или 0 |
                                                       |----------------|
         Текстовый буфер командной строки <------------|DWORD:указывает |
                                                       |      текст     |
                                                       |----------------|
         File Control Block 1:load @ 5Ch  <------------|DWORD:указывает |
         (FCB1-блок управления файлом 1:загрузка @ 5Ch)| FCB 1          |
                                                       |----------------|
         File Control  Block  2:load @ 6Ch <-----------|DWORD:указывает |
         (FCB2-блок управления файлом 2:загрузка @ 6Ch)| FCB 2          |
                                                       |----------------|
         Замечание: Все указатели DWORD хранятся как,  | OFFSET  (смеще-|
                    следующее  после SEGMENT (сег-     |  ние)          |
                    мента)                              \/\/\/\/\/\/\/\/

              Рис.3-13. Блок параметров для  функции  4Bh  (AL=0)  -
                                EXECUTE (выполнить)

После того, как резидентная подпрограмма или RTL будут отключены, необходимо выполнить второй шаг, заключающийся в восстановлении памяти. Память восстанавливается из MS-DOS посредством функции с номером 49h "Освободить распределенную память". MS-DOS безразлично, относится или нет восстанавливаемая память к программе, так что если адрес начала блока памяти занят резидентной подпрограммой, то память может быть освобождена и восстановлена. Установленная подпрограмма может обычно определить этот адрес, так как одной из ее опций является обеспечение кода функции вызова подпрограммы и сообщения ей о запрещении и удалении самой себя. Для подпрограмм, которые могут быть установлены посредством использования векторов прерываний, для целей инструктирования об удалении самой себя, может быть распределен второй вектор прерывания.


Если известно, что адрес сегмента вектора прерывания подпрограммы и адрес сегмента блока памяти подпрограммы одинаковы, то другим способом является написание программы чтения вектора, определения из него адреса сегмента блока памяти, и инструктирование MS-DOS об освобождении памяти.


В некоторых случаях ни один из этих способов не работает, так как MS-DOS не может восстановить всю память. Проблема скорее всего относится к внутренним проблемам MS-DOS, так как возникает неадекватное представление для выполнения некоторых противоречивых требований.


НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz