18 |Смещение таблицы настройки. Относительное смещение
|байтов от начала программного файла в таблице настрой-
|ки.
_________|______________________________________________________
1A |Номер перекрытия. Номер перекрытия, сгенерированный
|компоновщиком LINK.
_________|______________________________________________________
- 3-27 -
программы. Во время настройки начальная ссылка сегмента, включаю-
щая образ загрузки, обновляется для включения действительных зна-
чений сегмента. Этот процесс мы рассмотрим более подробно только
после того, как разберем один большой аспект файлов .EXE - на-
чальные значения распределения.
Блок начального распределения памяти .EXE
В примерах, представленных до сих пор, считалось само собой
разумеющимся, что MS-DOS при загрузке программы в память распре-
деляет всю оставшуюся память для этой программы. Так, в примере
SHOUMEM, показанном на Рис. 3-4, для программы SHOWMEM назначен
последний и наибольший блок памяти. Это явление было рассмотрено
в главе 2, в которой для программ, приведенных в листингах 2 -12
и 2-13, была использована функция модификации блока распределения
памяти (функция 4Ah). Но мы намекали и на другие способы получе-
ния свободной памяти для программ типа .EXE. Рис. 3-6 показывает
программу типа .EXE, которая имеет большой блок доступной памяти,
а последний элемент таблицы 3-3 говорит о том, что размер блока
начального распределения программы .EXE может быть изменен. Как
это получается?
Заголовок файла типа .EXE содержит два элемента, которые уп-
равляют точным предоставлением памяти программе при ее загрузке.
Этими двумя элементами являются MinAlloc - минимальное распреде-
ление памяти (по смещению 0Ah) и MaxAlloc - максимальное распре-
деление памяти (по смещению 0Сh). Элемент MinAlloc сообщает заг-
рузчику о том, какой объем памяти (в 16-байтовых параграфах)
должна иметь программа для выполнения, т.е. сколько байтов ис-
пользует программа на самом деле. Элемент MaxAlloc, с другой сто-
роны, сообщает загрузчику количество параграфов памяти, которое
программа требует распределить для нее.
Компоновщик MS-DOS обычно устанавливает значение элемента
MaxAlloc в 0FFFFh, указывающее на то, что программа желает почти
1 Мбайт памяти. Т.к. MS-DOS не может может иметь мегабайт памяти,
то она выделяет программе всю оставшуюся память. Однако, если бы
мы указали значение элемента MaxAlloc, равное значению элемента
MinAlloc, то программа получила бы требуемую ей память, а остав-
шаяся часть была бы доступна для распределения. Для этого имеется
два очень простых способа.
Языки программирования фирмы "Майкрософт", включая MASM, пос-
тавляются с утилитой, называемой EXEMOD. Эта утилита может быть
использована для отображения и модификации заголовка программы
типа .EXE. Рис.3-9 показывает, как необходимо выполнять использо-
вание утилиты EXEMOD для получения дампа и затем модификации па-
раметра MaxAlloc. Можно удивиться, увидев, что в примере значение
параметра MaxAlloc изменяется на значение 1, но из рассмотрения
Рис.3-10 можно видеть, как на самом деле выполняется модификация
размера памяти, требуемого для программы SHOWMEM, и как выполня-
ется освобождение памяти. Модифицированный образ программы
SHOWMEM в памяти очень похож на образ программы типа .EXE, приве-
денный на Рис.3-6, включая свободный блок.
C> exemod c:\guide\examples\showmem.exe
- 3-28 -
1 Microsoft R EXE File Header Utility Version 4.02
2 Copyright c Microsoft Corp 1985-1987. All rights reserved.
c:\guide\examples\showmem.exe (hex) (dec)
3 EXE size (bytes) CC5 3269
4 Minimum Load size (bytes) AC5 2757
5 Overlay number 0 0
6 Initial CS:IP 0093:0000
7 Initial SS:SP 0013:0800 2048
8 Minimum allocation (para) 0 0
9 Maximum allocation (para) FFFF 65535
10 Header size (para) 20 32
11 Relocation table offset 1E 30
12 Relocations entries 1 1
C> exemod c:\guide\examples\showmem.exe /max 1
9 Maximum allocation (para) FFFF 65535
Рис.3-9. Использование утилиты EXEMOD
для программных файлов типа .EXE:
1 - версия 4.02 утилиты заголовка файла типа EXE фирмы "Майкро-
софт"; 2 - авторское право фирмы "Майкрософт карпорэйшн" 1985-
1987 гг. все права зарезервированы; 3 - размер EXE (в байтах); 4
- минимальный размер для загрузки (в байтах); 5 - номер перекры-
тия; 6 - начальное значение CS:IP; 7- начальное значение SS:SP; 8
- минимальное распределение; 9 - максимальное распределение; 10 -
размер заголовка; 11 - смещение таблицы настройки; 12 - количест-
во настраиваемых элементов.
Увидев, что значения MinAlloc и MaxAlloc равны нулю, Вы уди-
витесь. Если это имеет место, то действительный размер минималь-
ного распределения для программы будет равен размеру самой прог-
раммы, и дополнительное пространство памяти не распределяется. 1
SM-ShowMem, Version 1.00 c Copyright 1988 2 MCB Size Owner
Command Line
------------------------------------------------------------
0A01 08D7 0008 DOS
12D9 00D3 12DA [ SHELL ]
13AD 0003 0000 [ available ]
13B1 0032 12DA [ SHELL ]
13E4 0004 13EA c:\bin\RETRIEVE.COM
13E9 00A9 13EA c:\bin\RETEIEVE.COM
1493 000F 14A4 s:\MODE.COM
14A3 0017 14A4 s:\MODE.COM
14BB 0010 14CD c:\ws2000\SWITCH.COM
14CC 0018 14CD c:\ws2000\SWITCH.COM
14E5 0011 14F8 c:\GUIDE\EXAMPLES\SHOWMEM.EXE
14F7 00D1 14F8 c:\GUIDE\EXAMPLES\SHOWMEM.EXE
15C9 8A36 0000 [ available ]
<<<------------- End of Memory Block List ------------->>> 3
Рис.3-10. Пример отображения из SHOWMEM с параметром MaxAlloc,
равным значению параметра MinAlloc:
1 - программа показа памяти - ShowMem, версия 1.00, авторское
право 1988; 2 - блок управления памятью, размер, владелец, ко-
мандная строка; 3 - конец списка блоков памяти.
- 3-29 -
Таким способом необходимо определять размер всех программных
файлов .EXE, и даже учитывать размер EXEMOD при создании команд-
ных файлов. Однако, при создании файлов .EXE имеется другой спо-
соб управления параметром MaxAlloc - способ использования перек-
лючателя "/CPARMAXALLOC:nnn" (сокращенно: "/CP:nnn") компоновщика
LINK, где nnn - значение параметра MaxAlloc, выраженное в параг-
рафах. Например, программа SHOWMEM может быть образована со зна-
чением параметра максимального распределения, равным 1, путем ис-
пользования следующей команды:
C> link /cp:1 showmem,,,stdlib.lib;
Загрузчик процесса .EXE MS-DOS
Теперь нам известны все составные части, входящие в програм-
мные файлы типа .EXE, и можно начать рассмотрение загрузки и вы-
полнения программ типа .EXE.Так же,как и для процессов типа .COM,
первый шаг состоит в установке контекста процесса, начиная с бло-
ка среды.
После установки среды либо из системных таблиц, либо из таб-
лиц владельца, в рабочую область считывается заголовок програм-
много файла .EXE. Используя значения MinAlloc и MaxAlloc и размер
образа программы (из размера страницы и размера заголовка),
MS-DOS определяет требуемый размер блока памяти и распределяет
его. Если значение параметра MaxAlloc равно 0FFFFh, то при этом
будет распределена вся память.
После распределения блока памяти, в начале блока процесса
создается PSP (сегмент программого префикса). PSP для программ
типа .EXE не отличается от программ типа .COM. Затем MS-DOS чита-
ет образ программы в память непосредственно выше PSP, считывает
таблицу настройки и продолжает настраивать образ программы.
Рис.3-11 показывает, как элементы в таблице настройки ссылаются к
образу программы. Все числа на рисунке и арифметические действия
выполняются в шестнадцатиричной системе счисления.
Первым шагом при настройке является вычисление адреса начала
сегмента. Он является адресом реальной памяти, который соответс-
твует адресу начала образа программы в файле. На Рис.3-11 блок
памяти процесса размещен по адресу сегмента, равному 1000. PSP
занимает 100 байтов или 10 сегментов. Адрес начала программного
сегмента в памяти равен тогда сегменту 1010:0000, и это есть ад-
рес, по которому загрузчик поместит образ программы.
После загрузки образа программы загрузчик должен обновить
или настроить каждую ссылку сегмента. Когда компоновщик LINK на-
чинает строить образ программы, он использует предполагаемый ба-
зовый сегмент 0000. На самом деле, программа загружается в сег-
мент 1010, так что к каждой ссылке сегмента необходимо добавить
1010. Загрузчик находит все эти ссылки путем использования таб-
лицы настройки, которая содержит указатель на каждую ссылку сег-
мента в программе.
Рис.3-11 содержит две ссылки на значения сегментов. Просле-
дим процесс настройки для далекого (far) вызова, размещенного по
0003:1234. Действительная ссылка сегмента находится в четвертом
и пятом байтах этой инструкции по адресу 0003:1237.
- 3-30 -
Программный файл
типа .EXE
--------------- Начальные CS:IP = 0000:0010
|Заголовок прог-| Начальный сегмент = +1010
|раммного файла | ----------
--------------- Действительные
значения = 1010:0010
--------------- |
Добавление| Таблица наст- | | ОБРАЗ ПРОГРАММЫ
адреса | ройки | | В ПАМЯТИ
начала | 0003:1237 --------.| --------------- 1000:0000
сегмента | 0005:ABCE -------.|| | Префикс прог- |
1010 --------------- ||| | раммного сег- |
||| | мента |