Файл EXE, который строит компоновщик состоит из двух частей: - управляющая информация для загрузчика. - собственно загрузочный модулъ. Информация для загрузчика, описанная ниже, расположена в начале файла и образует так называемый заголовок. Сразу за ним следует тело загрузочного модуля. Тело загузочного модуля начинается на грнице блока и представляет собой копию образа памяти задачи, которую построил ком- поновщик. Стандартная частъ заголовка имеет следующий формат: Смещение Содержимое 00-01 4D5A - "подписъ" компоновщика, указывающая, что файл является файлов EXE. 02-03 Длина образа задачи по модулю 512 (т.е. число полезных байт в последнем блоке). (Компоновшики версий до 1.10 помещали в это поле 04; если оно имеет такое значение, его рекомендуется игнорироватъ). 04-05 Длина файла в блоках. 06-07 Число элементов таблицы настройки адресов. 08-09 Длина заголовка в 16-ти байтных параграфах. Исполъзуется для выяснения начала тела загрузочного модуля. 0A-0B Минималъный объем памяти, которую нужно выделитъ после конца образа задачи. (в 16-ти байтных параграфах). 0C-0D Максималъный объем памяти, которую нужно выделитъ после конца образа задачи. (в 16-ти байтных параграфах). 0E-0F Сегментный адрес начала стекового сегмента относителъно начала образа задачи. 10-11 Значение SP при входе в задачу. 12-13 Контролъная сумма - нолъ минус резулътат сложения без переноса всех слов файла. 14-15 Значение IP (счетчика команд) при входе в задачу. 16-17 Сегментный адрес начала кодового сегмента относителъно начала образа задачи. 18-19 Адрес первого элемента таблицы настройки адресов относителъно начала файла. 1A-1B Номер сегмента перекрытий. (0 для корневого сегмента программы). Далее следует таблица настройки адресов. Таблица состоит из эле- ментов, число которых записано в байтах 06-07. Элемент таблицы настрой- ки состоит из двух полей: 2-х байтного смещения и 2-х байтного сегмен- та, и указывает слова в загрузочном модуле, содержащее адрес, который должен бытъ настроен на место памяти, в которое загруежается задача. Насторойка производится следующим образом: 1. В области памяти после резидентной части выполняющей загрузку программы строится Префикс Программного сегмента. 2. Стандартная частъ заголовка считывается в памятъ. - 2 - 3. Определятся длина тела загрузочного модуля (разностъ длины фай- ла 04-07 и длины заголовка 08-09 плюс число байт в последнем блоке 02-03). В зависимости от признака, указывающего загружатъ задачу в ко- нец памяти или в начало, определяется сегментный адрес для загрузки. Этот сегмент называется началъным сегментом. 4. Загрузочный модулъ считывается в началъный сегмент. 5. Таблица настройки порциями считывается в рабочую памятъ. 6. Для каждого элемента таблицы настройки к полю сегмента прибав- ляется сегментный адрес началъного сегмента. В резулътате элемент таб- лицы указывает на нужное слово в памяти; к этому слову прибавляется сегментный адрес началъного сегмента. 7. Когда таблица настройки адресов обработана, регистрам SS и SP придаются значения, указанные в заголовке, к SS прибавляется сегментный адрес началъного сегмента. В ES и DS засылается сегментный адрес начала Префикса Программного сегмента. Управление передается загруженной зада- че по адресу, указанному в заголовке (байты 14-17). 2.Структура программного сегмента При обращении к нерезидентной команде или вызове программы опера- цией Exec, DOS обределяет минималъный адрес, начиная с которого может бытъ загружена соответствующая программа. Эта областъ называется прог- раммным сегментом. По смещению 0000 в программном сегменте DOS формирует Префикс Программного сегмента (PSP). Сама программа загружется по смещению 0100. Программа завершается переходом по адресу 0000 в программном сег- менте, выполнив INT 20, выполнив INT 21 с AH=0 или AH=4C, или обратив- шисъ к подпрограмме по адресу 0050 в программном сегмент с AH=0 или AH=4C. Примечание: при завершении иначе, чем операцией 4C, программа должна предварителъно заслатъ в CS адрес начала своего программного сегмента. Все четыре способа возвращают управление в резидентную частъ COMMAND.COM (при этом операция 4C передает код завершения). Все четыре способа приводят к продолжению выполнения программы, обратившейся к операции Exec (4B). При этом вектора прерываний 22, 23 и 24 (заверше- ние, Ctrl-Break, фаталъная ошибка обмена) восстанавливаются из Префикса Программного сегмента возобновляемой задачи. Затем управление передает- ся по адресу завершения. Если программа возвращается в COMMAND.COM, то управление передается в нерезидентную частъ. Если это происходит во время выполнения командного файла, оно продолжается, иначе COMMAND вы- дает на терминал приглашение и ждет ввода следующей команды. Когда загруженная программ получает управление, имеют место следующие условия: Для всех программ: - В Префиксе Программного сегмент по смещению 2C передается адрес среды. Среда представляет собой последователъностъ строк ASCIIZ, вида параметр=значение Общая длина строк среды <= 32K байт; среда начинается с границы параграфа. После последней строки следует нулевой байт. Среда, переда- ваемая задаче от COMMAND, содержит, как минимум, параметр COMSPEC= (значение этого параметра - полное имя файла, содержащего исполъзуемый COMMAND.COM). Она также содержит значения, установленные командами PATH, PROMPT и SET (См. Главу 10). Передаваемая среда является копией среды родителъского процесса. Если задача остается резидентом, то пос- ледующие команды PATH, PROMPT и SET не будут воздействовтъ на ее среду. - 3 - - По смещению 0050 в Префиксе Программного сегмента содержится программа обращения к операциям DOS. Таким образом, занеся в AH номер операции, программа может вызватъ процедуры (LCALL) по адресу PSP + 50, а не обращатъся к прерыванию 21. - Адрес буфера DTA установлен на PSP +80. - Блоки управления файлами, расположенные по смещениям 5C и 6C в Префиксе Программного сегмента заполняются в соответствии с параметрами командной строки. При этом если соответствующий параметр включает имя каталога, в FCB заносится толъко код устройства, имя файла формируется неправилъно. - Неформатная частъ, начинающаяся со смещения 81, содержит символы командной строки после имени команды, включая все пробелы и разделите- ли. По смещению 80 помещена длина этой строки. Если командная строка включает параметры переназначения (на них указывают символы > и <) они не попадают сюда, так как переназначение прозрачно для программ. - Слово по смещению 6 содержит число байт в данном сегмен- те. - Регистр AX указывает, правилъно ли заданы имена устройств в параметрах: AL = FF - имя устройства для первого параметра задано неверно, иначе AL = 00; AH = FF - имя устройства для первого параметра задано неверно, иначе AH = 00. Для программ .EXE: - DS и ES указывают на начало Префикса Программного сегмента. - Регистры CS, IP, SS и SP получают значения, указанные компонов- щиком. Для программ .COM: - Все четыре сегментных регистра указывают на Префикс Программного сегмента. - Программе выделяется вся свободная памятъ. Если программа запус- кает другие программы операцией Exec, то она должна освободитъ для нее частъ памяти операцией Setblock (4A) - Счетчик команд IP получает значение 0100H. - Регистр SP указывает на конец программного сегмента. Длина сег- мента в ячейке 6 Префикса уменъшается на 0100H, чтобы освободитъ прост- ранство для стека такого размера. - На вершину стека помешается нулевое слово Префикс Программного сегмента имеет следующий формат (все числа шестнадцатеричные): - 4 - ---------------------------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ---------------------------------------------------------------- | INT | Top of | Re- | Long call to DOS | | 20H | memory |served | OP # bytes | | | | | CODE in segment | ---------------------------------------------------------------- | 8 | 9 | A | B | C | D | E | F | ---------------------------------------------------------------- | cont.segment | Terminate | Terminate |Ctrl-break exit| | of long call | address IP | address CS |address IP | ---------------------------------------------------------------- | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ---------------------------------------------------------------- |Ctrl-break exit Critical error exit address | Reserved | |address CS | IP CS | | ---------------------------------------------------------------- | 18 | 19 | 2A | 2B | 2C | 2D | 2E .... 4F | ---------------------------------------------------------------- | R e s e r v e d |Segment address| Reserved | | |of environment | | ---------------------------------------------------------------- | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ---------------------------------------------------------------- | DOS call | R e s e r v e d | ---------------------------------------------------------------- | 58 | 59 | 5A | 5B | 5C | 5D | 5E | 5F | ---------------------------------------------------------------- | R e s e r v e d | Unopened Standart FCB1 | ---------------------------------------------------------------- | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ---------------------------------------------------------------- | Unopened Standart FCB1 (cont.) | ---------------------------------------------------------------- | 68 | 69 | 6A | 6B | 6C | 6D | 6E | 6F | ---------------------------------------------------------------- | F C B 1 (cont.) | Unopened Standart FCB2 | ---------------------------------------------------------------- | 70 to 7F | ---------------------------------------------------------------- | Unopened Standart FCB2 (cont.) | ---------------------------------------------------------------- | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | ---------------------------------------------------------------- | Parm | Command parameters starting with leading blanks | | length| | ---------------------------------------------------------------- | F8 | F9 | FA | FB | FC | FD | FE | FF | ---------------------------------------------------------------- | C o m m a n d p a r a m e t e r s | ---------------------------------------------------------------- Примечания: 1. Граница памяти - номер первого свободного параграфа; напр. 1000 соответствует 64K. 2. Слово по смещению 6 содержит число байт в данном сегменте. 3. Слово по смещению 2C содержит сегментный адрес среды. 4. Программа не должна изменятъ частъ PSP от 00 до 5C. |