Поиск по сайту:
Программы типа .exe и .com различаются не только форматом исходного текста и процедурой создания исполняемого файла при трансляции, но и форматом загрузочного файла на диске. Программы загружаются в память для выполнения с помощью функции DOS Exec (Int 21h, функция 4Bh), играющей роль системного загрузчика. При этом, если имя программы вводится в командную строку с клавиатуры, то функция Exec вызывается командным процессором Command.com.
В дальнейшем изложении для сравнительной оценки параметров программ, выполненных в разных форматах, взята одна и та же простая программа с минимально возможным набором команд (с целью экономии места, отводимого для иллюстраций).
¨ Загрузка и выполнение .COM-программы
Программы типа .com после загрузки в память представляют собой немодифицированное представление программы на машинном языке на диске. Листинг трансляции и машинный код программы на диске приведён на рис П.1.3_1. Особенностью данного формата является тот факт, что, несмотря на местоположение данных в тексте программы, компоновщик Tlink размещает их в исполняемом файле после кода программы (рис. П.1.3_1, б).
Действия функции Exec при запуске программы типа .com выглядят следующим образом.
1. Запускаемой программе отводится вся свободная в данный момент оперативная память, в которой определяется начальный сегментный адрес программы.
2. По нулевому смещению в выделенном для программы сегменте памяти Exec создаёт специальную служебную структуру – префикс программного сегмента PSP, в котором содержится информация дляDOS об окружении программы. Впрочем, некоторые поля PSP используются и прикладными программистами, например, при разработке резидентных программ. Размер PSP всегда равен 100h или 256 байт.
а) Листинг prog_com. lst
Turbo Assembler Version 4.1
1
2 Ideal
3 0000 Model tiny
4 0000 Dataseg
5 0000 8F E0 AE A3 E0 A0 AC+ mes db 'Программа типа .com',10,13,'$'
6 AC A0 20 E2 A8 AF A0+
7 20 2E 63 6F 6D 0A 0D+
8 24
9 0016 Codeseg
10 org 100h
11 0100 proc main
12 0100 B4 09 mov ah,09h ;Вывод сообщения mes на экран
13 0102 BA 0000r mov dx,offset mes
14 0105 CD 21 int 21h
15 0107 B8 4C 00 exit: mov ax,04C00h ;Функция DOS 4Сh
16 010A CD 21 int 21h ;Вызов DOS. Останов
17 010C endp main
18 end main ;Конец программы/точка входа
Groups & Segments Bit Size Align Combine Class
Dgroup Group
_Data 16 0016 Word Public Data
_Text 16 010C Word Public Code
б) Машинный код исполняемого файла prog_com.com на диске объёмом 32 байта
00000: B4 09 BA 0C 01 CD 21 B8 00 4C CD 21 8F E0 AE A3 ┤○║♀☺=!╕ L=!Прог
00010: E0 A0 AC AC A0 20 E2 A8 AF A0 20 2E 63 6F 6D 0A рамма типа .com◙
00020: 0D 24 ♪$
Рис. П.1.3_1. Листинг и машинный код программы типа .com
Таблица П.1.3_1
Содержимое префикса программы PSP
Смещение |
Число байтов |
Описание |
00h |
2 |
Инструкция INT 20h |
02h |
2 |
Сегментный адрес первого свободного байта за пределами программы |
0Ah |
4 |
Адрес перехода в Command после завершения программы (Int 22h) |
0Eh |
4 |
Адрес обработчика Ctrl+C (Int 23h) |
12h |
4 |
Адрес обработчика критической ошибки (Int 24h) |
16h |
2 |
Сегмент PSP родителя |
18h |
20 |
Таблица файлов задания (Job file Table – JFT) |
2Ch |
2 |
Сегментный адрес блока окружения программы |
2Eh |
4 |
SS:SP на входе в последний вызов int 21h |
32h |
2 |
Количество байтов в JFT (по умолчанию 20) |
34h |
4 |
Адресный указатель на JFT (по умолчанию PSP:0018h) |
80h |
1 |
Длина командной строки в байтах |
81h |
127 |
Параметры командной строки при запуске программы ) и 0Dh |
3. Сразу вслед за PSP загружается сама com-программа со следующей настройкой регистров процессора: cs = ds = ss = es указывают на начальный сегмент программы, регистр ip инициализируется числом 100h (это размер PSP), а регистр sp – числом 0FFFEh. При этом образ программы в памяти после PSP в точности соответствует машинному коду программы на диске (рис. П.1.3_1, б). Таким образом, программный код, данные и стек com-программы размещаются в одном сегменте оперативной памяти объёмом 64 Кбайта, так как регистр указателя вершины стека инициализируется числом 0FFFEh.
4. Для исполнения загруженной com -программы Exec передает управление по адресу cs:100h (по этому адресу обязательно должна находиться первая исполняемая команда). После завершения программы управление передается обратно в Exec, а оттуда – родительской программе – "предку" (при запуске из командной строки – командному процессору Command.com).
¨ Загрузка и выполнение .exe-программы
В настоящее время существуют три формата .exe-программ:
– MZ-формат (разработан фирмой Microsoft для поддержки многосегментных программ в среде MS DOS);
– NE-формат (Windows 3.1);
– PE-формат (Windows 95/98/2000).
MZ-формат, построенный компоновщиком и хранимый на диске, состоит из заголовка и собственно загрузочного модуля (рис. П.1.3_2).
В заголовке, состоящем из одного или нескольких блоков размером
512 байт, содержится информация для настройки значений сегментных регистров (в том числе регистров ip и sp) процессора, используемая при загрузке
программы в память для её исполнения. Формат заголовка приведён в
табл. П.1.3_2.
а) Листинг prog_exe.lst
Turbo Assembler Version 4.1
1
2 IDEAL
3 0000 MODEL small
4 0000 stack 32
5 0020 10*(3F) db 16 dup('?') ;Введено с целью просмотра сегмента
; стека программой – оболочкой
6 0030 DATASEG
7 0000 8F E0 AE A3 E0 A0 AC+ mes db 'Программа типа .exe',10,13,'$'
8 AC A0 20 E2 A8 AF A0+
9 20 2E 65 78 65 0A 0D+
10 24
11 0016 CODESEG
12 0000 B8 0000s Start: mov ax,@data ;Установка в ds адреса
13 0003 8E D8 mov ds,ax ;сегмента данных
14 0005 B4 09 mov ah,09h ;Вывод сообщения mes на экран
15 0007 BA 0000r mov dx,offset mes
16 000A CD 21 int 21h
17 000C B8 4C00 Exit: mov ax,04C00h
18 000F CD 21 int 21h ;Вызов DOS. Останов программы
19 END Start ;Конец программы/точка входа
Groups & Segments Bit Size Align Combine Class
Dgroup Group
Stack 16 0030 Para Stack Stack
_Data 16 0016 Word Public Data
_Text 16 011 Word Public Code
б) Машинный код исполняемого файла prog_exe.exe на диске объёмом 624 байта
Заголовок программы (512 байт)
00000: 4D 5A 70 00 02 00 01 00 20 00 00 00 FF FF 04 00 MZp ☻ ☺ ♦
00010: 30 00 00 00 00 00 00 00 3E 00 00 00 01 00 FB 71 0 > ☺ √q
00020: 6A 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 jr
00030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 ☺
00040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...................................
001F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Загрузочный модуль: Сегмент кода (32 байта)
00200: B8 02 00 8E D8 B4 09 BA 00 00 CD 21 B8 00 4C CD ╕☻ o╪┤o║ ═!╕ L=
00210: 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 !
Сегмент данных (32 байта)
00220: 8F E0 AE A3 E0 A0 AC AC A0 20 E2 A8 AF A0 20 2E Программа типа .
00230: 65 78 65 0A 0D 24 00 00 00 00 00 00 00 00 00 00 exe◙♪$
Сегмент стека (48 байт)
00240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00260: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F ????????????????
Рис. П.1.3_2. Листинг и машинный код программы типа .exe
Таблица П.1.3_2
Формат заголовка исполняемого .exe – файла на диске
Смещение |
Число |
Описание |
00h |
2 |
Сигнатура "MZ" (Mark Zbikowski) или код 4D5A |
02h |
2 |
Остаток от деления размера загрузочного модуля на 512. (для нашего примера 624 -512=112=70h) |
04h |
2 |
Размер файла в блоках по 512 байт, округленный в большую сторону |
06 |
2 |
Число элементов таблицы настройки адресов |
08h |
2 |
Размер заголовка в параграфах |
0Ah |
2 |
Минимальное число параграфов, требуемых программе дополнительно к её образу на диске |
0Ch |
2 |
Максимальное число параграфов, требуемых программе дополнительно к её образу на диске (по умолчанию FFFFh) |
0Eh |
2 |
Смещение в параграфах сегмента стека в загрузочном модуле (SS0) |
10h |
2 |
Значение регистра SP0 |
12h |
2 |
Поразрядная контрольная сумма EXE- файла |
14h |
2 |
Значение регистра IP0 при входе в программ |
16h |
2 |
Смещение в параграфах сегмента кода в загрузочном модуле (CS0) |
18h |
2 |
Расстояние в байтах от начала файла до первого элемента таблицы настройки адресов |
1Ah |
2 |
Содержат «0», если программа является резидентной, или отличное от нуля число, если данная часть программы является оверлейной |
1Ch |
6 |
Различные сигнатуры, в том числе версия Tlink (смещение 1Fh) |
Действия MS DOS при запуске .exe-программы отличаются от действий при запуске программы типа .com, хотя в обоих случаях используется одна и та же функция Exec.
1. Запускаемой программе отводится вся свободная в данный момент оперативная память, в которой определяется начальный сегментный адрес программы (NS0).
2. По нулевому смещению в выделенном для программы сегменте памяти Exec создаёт служебную структуру – префикс программного сегмента PSP. Его размер, как и для COM-программ, равен 256 байт.
3. Вслед за PSP размещается загрузочный модуль программы, а заголовок и таблица настройки в память не копируются. После этого выполняется так называемая настройка адресов.
4. Суть настройки состоит в следующем: компоновщик (Tlink или какой-либо другой) строит exe-модуль относительно некоторого "базового адреса" (в MS DOS программы могут загружаться в произвольную область памяти). Поэтому при загрузке программы к каждому сегментному адресу прибавляется значение начального сегмента программы (NS0). Элементы, требующие настройки, указываются в таблице настройки. Таким образом, устанавливаемые значения регистров для программы рис. П.1.3_2 примут следующие значения:
– DS = ES = NS0;
– CS = NS0 + 10h + CS0=NS0 +10h;
– SS = NS0 + 10h + SS0=NS0 + 14h;
– IP = IP0 =00h , SP = SP0 = 30h
Здесь CS0, SS0, IP0 и SP0 берутся загрузчиком Exec из заголовка exe-файла, а значение 10h – резервирует пространство (в параграфах) для PSP.
5. После загрузки программы начинается процесс её исполнения, для чего Exec передает управление по адресу cs:ip.