|
|
|
|
Завершение программы
Имеется несколько различных способов завершения выполнения обычной программы. Наиболее общими являются использование функции AH=4Ch и функции
AH=00h прерывания int 21h. Все запросы завершения обрабатывает общая подпрограмма DOS. При завершении программы эта подпрограмма копирует адреса
критической ошибки (int 24h) и прерывания ISR (int 23h), сохраненные в PSP для IVT, закрывает все файлы и освобождает всю память, относящуюся к
текущему процессу. Управление возвращается по адресу завершения (int 22h). Если завершающий процесс не модифицировал вход IVT для адреса завершения,
то программа, загрузившая программу завершения, снова получит управление для выполнения инструкции, непосредственно следующей за запросом загрузки.
Затем, как обычно, управление возвращается в файл COMMAND.COM. Критические ошибки вызывают аварийные завершения. Одна и та же программа обрабатывает
запросы аварийного и обычного завершения, различие заключается лишь в выработке разного кода завершения, сохраняемого во внутренней переменной DOS.
Освобождение памяти является простым процессом. DOS распределяет память на блоки. Каждому блоку памяти непосредственно предшествует 16-байтовый блок
управления памятью (MCB). Область MCB содержит размер следующего блока и записи PSP владельца. Слово, стоящее во главе списка, содержит сегмент
первого блока управления памятью. Подпрограмма завершения DOS просматривает список MCB для нахождения блоков, которыми владеет текущий процесс. Всякий
раз, когда подпрограмма завершения находит очередной блок, которым владеет процесс, она устанавливает поле владельца MCB в нуль, указывая, тем самым,
что блок свободен. Таким образом, при просмотре MCB освобождаются все блоки памяти, которыми владел завершаемый процесс, включая операционную среду. Для
освобождения своей среды программе не нужно предпринимать специальных действий.
Подпрограмма завершения DOS получает адрес JFT из PSP текущего (завершающего) процесса и просматривает JFT для поиска открытых файлов. При этом
подпрограмма завершения закрывает каждый открытый файл. Для каждого открытого файла подпрограмма закрытия уменьшает счетчик ссылок SFT. Если счетчик
ссылок станет нулевым и файлом владеет текущая программа, то подпрограмма закрытия освобождает вход SFT. Входы, соответствующие наследуемым файлам,
будут иметь счетчики ссылок, значения которых больше 1; входы SFT для этих ссылок останутся. (Так как завершающая программа все еще имеет текущий PSP, то
любая попытка закрытия этих входов приведет к отказу; поле "владелец PSP" этих входов SFT содержит файл COMMAND.COM, выступающий в качестве их
владельца).
В DOS имеется две функции "завершить и оставить резидентной" - int 27h и int 21h AH=31h. Функция int 27h является устаревшей и внутри DOS она
отображается в запрос int 31h. Запросы "завершить и оставить резидентной" обрабатываются одной и той же подпрограммой завершения. При выполнении
запроса "завершить и оставить резидентной" подпрограмма завершения не закрывает никакие файлы и не освобождает никакую память, но она модифицирует
размер блока памяти, содержащий PSP. Завершающая программа указывает размер нового блока памяти в качестве аргумента для запроса "завершить и оставить
резидентной". Любые индикаторы обработки, которые были допустимы перед выдачей запроса "завершить и оставить резидентной", будут действительны и
после повторной активации TSR.
|
|