Процесс загрузки программ в память
Загрузка COM- и EXE-программ происходит по-разному, однако есть некоторые действия, которые операционная система выполняет в обоих случаях одинаково.
Определяется наименьший сегментный адрес свободного участка памяти для загрузки программы (обычно DOS загружает программу в младшие адреса памяти, если при редактировании не указана загрузка в старшие адреса).
Создаются два блока памяти (и, следовательно, два блока MCB, описанные ранее) - блок памяти для переменных среды и блок памяти для PSP и программы.
Для DOS версии 3.х и старше в блок памяти переменных среды помещается путь файла программы.
Заполняются поля префикса сегмента программы PSP в соответствии с характеристиками программы (количество памяти, доступное программе, адрес сегмента блока памяти, содержащего переменные среды и т.д.)
Устанавливается адрес области Disk Transfer Area (DTA) на вторую половину PSP (PSP:0080).
Анализируются параметры запуска программы на предмет наличия в первых двух параметрах идентификаторов дисковых устройств. По результатам анализа устанавливается содержимое регистра AX при входе в программу. Если первый или второй параметры не содержат правильного идентификатора дискового устройства, то соответственно в регистры AL и AH записывается значение FF.
А дальше действия системы по загрузке программ форматов COM и EXE будут различаться.
Для COM-программ, которые представляют собой двоичный образ односегментной программы, выполняется чтение файла программы с диска и запись его в память по адресу PSP:0100. Вообще говоря, программы типа COM могут состоять из нескольких сегментов, но в этом случае они должны сами управлять содержимым сегментных регистров, используя в качестве базового адреса адрес PSP.
После загрузки файла операционная система для COM-программ выполняет следующие действия:
сегментные регистры CS, DS, ES, SS устанавливаются на начало PSP;
регистр SP устанавливается на конец сегмента PSP;
вся область памяти после PSP распределяется программе;
в стек записывается слово 0000;
указатель команд IP устанавливается на 100h (начало программы) с помощью команды JMP по адресу PSP:100.
Загрузка EXE-программ происходит значительно сложнее, так как связана с настройкой сегментных адресов:
Считывается во внутренний буфер DOS форматированная часть заголовка файла.
Определяется размер загрузочного модуля по формуле:
size=((file_size*512)-(hdr_size*16)-part_pag
Определяется смещение начала загрузочного модуля в EXE-файле как hdr_size*16.
Вычисляется сегментный адрес для загрузки START_SEG, обычно используется значение PSP+10h.
Загрузочный модуль считывается в память по адресу START_SEG:0000.
Сканируются элементы таблицы перемещений, располагающейся в EXE-файле со смещением relt_off.
Для каждого элемента таблицы:
1. Считывается содержимое элемента таблицы как два двухбайтных слова (OFF,SEG).
2. Вычисляется сегментный адрес ссылки перемещения
REL_SEG = (START_SEG + SEG)
3. Выбирается слово по адресу REL_SEG:OFF, к этому слову прибавляется значение START_SEG, затем сумма записывается обратно по тому же адресу.
Заказывается память для программы, исходя из значений min_mem и max_mem.
Инициализируются регистры, и программа запускается на выполнение.
При инициализации регистры ES и DS устанавливаются на PSP, регистр AX устанавливается так же, как и для COM-программ, в сегментный регистр стека SS записывается значение START_SEG + ss_reg, а в SP записывается sp_reg.
Для запуска программы в CS записывается START_SEG+cs_reg, а в IP - ip_reg. Такая запись невозможна напрямую, поэтому операционная система сначала записывает в свой стек значение для CS, затем значение для IP и после этого выполняет команду дальнего возврата RETF (команда возврата из дальней процедуры).
Содержание раздела