MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 18, М.: Диалог-МИФИ, 1995, 254 стр. 5.5. Выгрузка резидентной программы из памятиНапомним, что для выгрузки программы TSRDEMO из памяти ее нужно запустить с параметром u. Что происходит в этом случае? Функция main вызывает функцию unload. Та, в свою очередь, пытается выполнить удаление копии программы TSRDEMO из памяти, вызывая для этого функцию tsrunload. В зависимости от успеха этой операции функция unload выводит на экран соответствующее сообщение. Функция tsrunload составлена на языке ассемблера. Ее исходный текст вы сможете найти в листинге 5.3. Кратко о том, что делает эта функция. Прежде всего, она сохраняет содержимое регистров SS:SP и DS в глобальных переменных. Затем она загружает адрес точки входа ExitTSR в регистры BX:DX и вызывает прерывание INT 2Fh , передавая в регистре AX команду выгрузки программы из памяти - значение FF01h. Теперь в дело включается обработчик прерывания INT 2Fh , установленный загруженной резидентной программой TSRDEMO. Вот соответствующий фрагмент этого обработчика: else if(ax == 0xff01) { ExitAddress = ((long)bx << 16) + dx; if(!tsr_already_active) { _enable(); tsr_exit(); ax = 0xFFFF; tsr_already_active = -ax; } } Полученный адрес сохраняется в глобальной переменной ExitAddress, вслед за чем вызывается функция tsr_exit. Эта функция устанавливает стек, зарезервированный для работы при активизации программы, вслед за чем пытается восстановить переназначенные при установке векторы прерываний. Для восстановления используется функция RestoreIntVect, которая проверяет, не были ли переназначены векторы прерывания еще раз, например, другой резидентной программой, запущенной после программы TSRDEMO. Если все векторы прерываний удалось восстановить, резидентную программу можно удалить из памяти. Для этого используется простой способ: резидентная программа делается текущей, после чего ее работа завершается при помощи функции 4Ch прерывания INT 21h . Это стандартный способ завершения работы программы, при котором MS-DOS удаляет все связанные с ней блоки памяти. При невозможности восстановления векторов прерывания резидентная программа остается в памяти, но активизации не поддается из-за того что слово памяти, отведенное для флага tsr_already_active, записывается значение -FFFFh. |