.EXE
Исполняемый файл DOS MZ | |
---|---|
![]() | |
Расширение | .exe |
Сигнатура | MZ или ZM |
Разработчик | Microsoft |
Тип формата | двоичный, исполняемый, объектный, динамическая библиотека |
Расширен из | .COM |
Развит в |
New Executable Linear Executable Portable Executable |
.EXE (сокр. англ. executable — исполнимый) — расширение исполняемых файлов, применяемое в операционных системах DOS, Windows, Symbian OS, OS/2 и в некоторых других, соответствующее ряду форматов. Кроме объектного кода может содержать различные метаданные (ресурсы, цифровая подпись[1]).
Форматы .EXE
- MZ — 16-битный формат, основной формат файлов .EXE в DOS.
- EXE-файлы для Windows и OS/2 используют другие форматы для основной части программы, но всё равно начинаются с заглушки в формате MZ, которая, как правило, при попытке запустить файл в DOS выводит сообщение
This program cannot be run in DOS mode.
(«Эту программу невозможно запустить в режиме DOS») и завершает выполнение, хотя теоретически может запускать некий произвольный код, работоспособный в DOS.
- EXE-файлы для Windows и OS/2 используют другие форматы для основной части программы, но всё равно начинаются с заглушки в формате MZ, которая, как правило, при попытке запустить файл в DOS выводит сообщение
- NE — 16-битный формат, использовался в Windows 3.x[2], OS/2 и MS-DOS.
- LE — смешанный 16- и 32-битный формат, ранее использовался в OS/2 и Windows (VxD).
- LX — 32-битный формат, используется в OS/2.
- PE — 32- и 64-битный формат, используется в современных версиях Windows, начиная с Windows NT и Windows 95.
Структура файлов
Файл EXE, создаваемый компоновщиком, состоит из двух частей:
- управляющая информация для загрузчика;
- загрузочный модуль.
Информация для загрузчика, описанная ниже, расположена в начале файла и образует так называемый заголовок. Сразу за ним следует тело загрузочного модуля, представляющее собой копию образа памяти задачи, построенной компоновщиком.
Стандартная часть заголовка имеет следующий формат[3]:
- 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-байтного сегмента, и указывает слова в загрузочном модуле, содержащее адрес, который должен быть настроен на место памяти, в которое загружается задача. Настройка производится следующим образом:
- В области памяти после резидентной части выполняющей загрузку программы строится префикс программного сегмента (PSP);
- Стандартная часть заголовка считывается в память;
- Определяется длина тела загрузочного модуля (разность длины файла 04-07 и длины заголовка 08-09 плюс число байт в последнем блоке 02-03). В зависимости от признака, указывающего загружать задачу в конец памяти или в начало, определяется сегментный адрес для загрузки. Этот сегмент называется начальным сегментом;
- Загрузочный модуль считывается в начальный сегмент;
- Таблица настройки порциями считывается в рабочую память;
- Для каждого элемента таблицы настройки к полю сегмента прибавляется сегментный адрес начального сегмента. В результате элемент таблицы указывает на слово в памяти, к которому прибавляется сегментный адрес начального сегмента;
- Когда таблица настройки адресов обработана, в регистры SS и SP записываются значения, указанные в заголовке, а к SS прибавляется сегментный адрес начального сегмента. В ES и DS записывается сегментный адрес начала PSP. Управление передается по адресу, указанному в заголовке (байты 14-17).
Структура программного сегмента
![]() | В разделе не хватает ссылок на источники (см. рекомендации по поиску). |
При обращении к нерезидентной команде или вызове программы операцией 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, вида параметр=значение. Общая длина строк среды не более 32 Кбайт; среда начинается с границы параграфа. После последней строки следует нулевой байт. Среда, передаваемая задаче от COMMAND, содержит, как минимум, параметр COMSPEC=(значение этого параметра — полное имя файла, содержащего используемый COMMAND.COM). Она также содержит значения, установленные командами PATH, PROMPT и SET. Передаваемая среда является копией среды родительского процесса. Если задача остается резидентом, то последующие команды PATH, PROMPT и SET не будут воздействовать на её среду.
- По смещению 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, чтобы освободить пространство для стека такого размера.
- На вершину стека помешается нулевое слово.
Примечания
- ↑ Windows Authenticode Portable Executable Signature Format (англ.). Дата обращения: 11 декабря 2009. Архивировано из оригинала 1 марта 2012 года.
- ↑ How to open a .DLL or .EXE file in Resource Editor (англ.). Дата обращения: 11 декабря 2009. Архивировано из оригинала 1 марта 2012 года.
- ↑ Load Windows Programs From the DOS Prompt With WINSTART // PC Mag. — № 30 июня 1992.
Ссылки
- EXE Format (англ.) — формат заголовка MZ
![]() | В статье не хватает ссылок на источники (см. рекомендации по поиску). |