Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

MS-DOS для программиста

© Александр Фролов, Григорий Фролов
Том 18, М.: Диалог-МИФИ, 1995, 254 стр.

[Назад] [Содеожание] [Дальше]

3.2. Процесс загрузки программ в память

Загрузка com- и exe-программ происходит по-разному, однако есть некоторые действия, которые операционная система выполняет в обоих случаях одинаково:

  • определяется сегментный адрес свободного участка памяти для загрузки программы (обычно MS-DOS загружает программу в младшие адреса памяти, если при редактировании не указана загрузка в старшие адреса);
  • создаются два блока памяти (и, следовательно, два блока MCB , описанные во второй главе) - блок памяти для переменных среды, а также блок памяти для PSP и программы;
  • в блок памяти переменных среды помещается путь к файлу программы;
  • заполняются поля префикса сегмента программы PSP в соответствии с характеристиками программы (количество памяти, доступное программе, адрес сегмента блока памяти, содержащего переменные среды и т. д.);
  • адрес области Disk Transfer Area (DTA ) устанавливается на вторую половину PSP (PSP:0080);
  • анализируются параметры запуска программы на предмет наличия в первых двух параметрах идентификаторов дисковых устройств. По результатам анализа устанавливается содержимое регистра AX при входе в программу. Если первый или второй параметры не содержат правильного идентификатора дискового устройства, то соответственно в регистры AL и AH записывается значение FFh.

А дальше действия системы по загрузке com- и exe-программ будут различаться.

Для com-программ, которые представляют собой двоичный образ односегментной программы, выполняется чтение файла программы с диска и запись его в память по адресу PSP :0100h.

Размер обычных com-программ, как мы уже говорили, не превышает 64 Кбайт, так как они состоят только из одного сегмента. Но, строго говоря, com-программы могут состоять и из нескольких сегментов. В этом случае они должны сами управлять содержимым сегментных регистров, используя в качестве базового адрес PSP .

Загрузка COM-программы

В процессе загрузки com-программы операционная система выполняет следующие действия:

  • сегментные регистры CS, DS, ES, SS устанавливаются на начало PSP ;
  • регистр SP устанавливается на конец сегмента PSP ;
  • вся область памяти после PSP распределяется программе;
  • в стек записывается слово 0000;
  • указатель команд IP устанавливается на 100h (начало программы) с помощью команды JMP по адресу PSP :100h.

Загрузка EXE-программы

Загрузка exe-программы происходит значительно сложнее, так как связана с настройкой сегментных адресов:

  • во внутренний буфер MS-DOS считывается форматированная часть заголовка файла;
  • определяется размер загрузочного модуля по формуле:
size = ((file_size * 512) - (hdr_size * 16) - part_pag
  • определяется смещение начала загрузочного модуля в exe-файле по формуле:
START_OFF = hdr_size * 16;
  • вычисляется сегментный адрес для загрузки START_SEG, для чего используется следующая формула:
START_SEG = <сегментный адрес PSP > + 10h;
  • загрузочный модуль считывается в память по адресу START_SEG:0000;
  • сканируются элементы таблицы перемещений, располагающейся в exe-файле со смещением relt_off;
  • для каждого элемента таблицы выполняются следующие действия:

- считывается содержимое элемента таблицы как два двухбайтных слова (OFF, SEG);

- вычисляется сегментный адрес ссылки перемещения по формуле:

REL_SEG = (START_SEG + SEG)

- выбирается слово по адресу 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 (команда возврата из дальней процедуры).

[Назад] [Содеожание] [Дальше]