|
|
|
|
Как определить, установлены ли резидентные программы?
До сих пор мы предполагали, что библиотека исполняющей системы (RTL) должна быть загружена в память, и только после этого должны стартовать
программы, которые ее используют. При некоторых обстоятельствах RTL может всегда находиться в памяти. Чем загружать повторную копию RTL, загрузчик
сначала должен определить загружена ли уже RTL в память, и загружать ее только тогда, если она отсутствует в памяти. Имеется два способа определения
наличия RTL в памяти, которые оба зависят от использования предварительно назначенного вектора прерывания для доступа к RTL.
Первый способ - чтение содержимого вектора прерывания посредством функции с кодом 35h "Получить вектор прерывания" для определения начального
адреса подпрограммы обслуживания прерывания (ISR - Interrupt service routine). Следующий шаг состоит в том, чтобы поместить в регистры DS и SI
начальный адрес устанавливаемой существующей подпрограммы. Затем выполняется инструкция CMPS (сравнение строк) для сравнения некоторого количества
байтов (в регистре CS) двух секций программы. Если результат сравнения положительный, то подпрограмма уже представлена в памяти. Если сравнение не
произошло, то подпрограмма не была установлена в памяти. Эффективность этого способа намного упадет, если все RTL (или резидентные подпрограммы) будут
начинаться с одинаковой последовательности инструкций. И, наоборот, эффективность может сильно возрасти, если все резидентные подпрограммы будут
содержать блок заголовка, показанный в листинге 3-7, и который уникально идентифицирует каждую резидентную подпрограмму.
Второй способ проверки наличия RTL или резидентной подпрограммы в памяти, требует, чтобы все неиспользуемые векторы прерывания (в больших системах
от вектора 40h до вектора 0FFh) были установлены в известное состояние. Это состояние может быть либо верхней, либо нижней памятью (0000:0000 или
FFFF:FFFF), или адресом инструкции IRET. В MS-DOS версии 2.0 и выше вектор 28h всегда указывает на ячейку инструкции IRET, хотя это не гарантируется!
Более элегантным решением для обработки незапрошенных прерываний и инициализации всех неиспользуемых векторов прерываний для указания на эту
подпрограмму (смотри главу 6 "Устанавливаемые драйверы устройств") является установка драйвера псевдо-устройства. Этот драйвер может затем содержать
инструкцию IRET, отчет об ошибках, выдаваемый на консоль, или все, что потребуется. При постоянном распределении одного вектора для постоянного
указания на драйвер незапрошенных прерываний (например, вектор 40h) программа установки может прочитать и сравнить этот вектор и вектор резидентной
подпрограммы, чтобы убедиться в том, была ли уже резидентная программа установлена в памяти.
Листинг 3-7. Идентификация входных строк подпрограммы
----------------------------------------------------------------
enter: jmp start ; обход области данных
db '<имя подпрограммы>' ; здесь задается имя подпр-мы
... ... ; область данных
start: <начало программного кода>
... ...
----------------------------------------------------------------
|
|
|