|
Link:
линкер модулей
3. LINK: линкер модулей.
------------------------
3.1. Общие сведения.
Объектный линкер предназначен для создания
исполнительных файлов из объектных файлов, сформированных
MASM или компиляторами C или PASCAL.
LINK формирует переместимый исполнительный код,
снабженный информацией перемещения, используя которую,
MS-DOS сможет загрузить в память и исполнить соответствующую
программу.
LINK может формировать программы, содержащие свыше 1М
кода и данных.
Воспринимая в качестве входа 2 файла, LINK может
формировать 2 выходных файла, как показано на рис.3.1.
_____________ _____________
| | | |
| имя.LIB |---------- ---->| имя.MAP |
| (библ-ка) | | | | (план) |
|___________| | | |___________|
| |
| |
| _____________ |
| | | |
| | | |
|----->| LINK |----|
| | | |
| |___________| |
| |
| |
_____________ | | _____________
| | | | | |
| имя.OBJ | | | | имя.EXE |
| (объектн. |---------- ---->| (исполнит.|
| файл) | | файл) |
|___________| |___________|
Рис. 3.1. Работа LINK.
Расширения имен файлов, показанные на рисунке
принимаются по умолчанию.
Объектный файл содержит объектные модули программных
- 14 -
сегментов, сформированные MASM или компилятором языка
высокого уровня.
Библиотеки содержат наборы модулей, на которых могут
ссылаться программные сегменты в объектном файле.
Библиотечные файлы формируются при помощи утилиты LIB.
Основным результатом работы LINK является
исполнительный файл, содержащий программу в виде, пригодном
для загрузки в память и исполнения. Некоторые особенности
формирования исполнительного файла описаны в п.3.4.
Файл плана является необязательным и содержит, если он
формируется, некоторую диагностическую и служебную
информацию, которая затем при посредстве утилиты MAPSYM
может быть использована в процессе отладки программы.
Файл плана содержит имена, загрузочные адреса и длины
всех сегментов программы. Кроме того, сюда входят имена и
загрузочные адреса групп в программе, адрес точки входа, а
также сообщения о возможных ошибках.
Если задана опция /MAP, в файл включаются имена общих
символов и их загрузочные адреса.
Если заданы опции /HIGH или /DSALLOCATE и объем
программы и данных в совокупности не превышает 64К, план
может содержать символы с необычно большими адресами
сегментов. Эти адреса отражают переменные, расположенные
ниже действительного начала сегмента. Пример:
FFF0:0A20 TEMP
Адрес TEMP - 00:920h.
Необходимо иметь ввиду, что, кроме двух выходных
файлов, LINK может формировать временный файл с именем
VM.TMP. Это происходит в том случае, когда линкеру не
хватает оперативной памяти. Соэдание файла VM.TMP
сопровождается сообщением на консоли и всегда осуществляется
в текущем подоглавлении. В этом случае нельзя использовать
опцию /PAUSE и снимать дискету, если она находится на
активном драйве, до того, как LINK не уничтожит файл VM.TMP.
Не рекомендуется создавать в текущем подоглавлении файл с
таким именем, который в этом случае может быть испорчен.
3.2. Запуск LINK.
Запуск LINK может быть осуществлен тремя способами:
1. С использованием подсказок.
2. При помощи командной строки DOS.
3. С использованием файла ответа.
Для запуска LINK с использованием подсказок необходимо
- 15 -
ввести командную строку, содержащую только имя линкера LINK
со спецификацией подоглавления, если она требуется. LINK
перейдет в диалоговый режим и серией подсказок запросит у
пользователя информацию о следующих файлах (ответ
заключается в наборе требуемых символов и нажатии клавиши
ENTER):
1. Имя объектного файла. Если при ответе не указано
расширение, предполагается OBJ. Если нужно
определить несколько файлов, их имена разделяются
символом + . Если все имена не помещаются на одной
строке, ввод имен можно продолжить, поставив символ
+ в последнюю позицию текущей строки. В этом
случае LINK повторит запрос для ввода
дополнительных имен.
2. Имя исполнительного файла. Если при ответе не
указано расширение, предполагается EXE. Базовое имя
исполнительного файла по умолчанию совпадает с
базовым именем объектного файла.
3. Имя файла плана модуля. Если при ответе не указано
расширение, предполагается MAP. Базовое имя по
умолчанию NUL.
4. Имя библиотеки. Если при ответе не указано
расширение, предполагается LIB. Можно задавать
несколько имен библиотек по аналогии с OBJ-файлами.
Если, не вводя имени, сразу нажать ENTER,
библиотеки использоваться не будут.
В каждом ответе после символа / могут быть заданы
опции LINK, которые описаны в п.3.3.
Если в каком-либо ответе специфицирован символ ; ,
LINK выйдет из диалогового режима и установит оставшиеся
имена по умолчанию из следующего списка:
<имя объектного файла>.EXE
NUL.MAP
Библиотеки не используются.
В любом ответе также могут быть заданы ответы на
несколько следующих подсказок. В этом случае один ответ от
другого отделяется запятой.
Для запуска LINK посредством командной строки,
необходимо ввести командую строку следующего вида:
LINK <имя объектного файла>[,[<имя исполнительного файла>]
[,[<имя файла плана>][,[<имя библиотеки>]]]][<опции>][;]
Символ ; может быть специфицирован в любом месте
командной строки до того, как были определены все файлы. В
этом случае имена оставшихся неопределенными файлов
принимаются по умолчанию из приведенного выше списка. Из
этого же списка принимаются по умолчанию имена файлов,
спецификация которых в командной строке опущена (посредством
лишней запятой).
Если в командной строке обнаружена ошибка, об этом
сообщается через консоль, и LINK переходит в диалоговый
- 16 -
режим.
Если специфицирована хотя бы одна из опций /MAP или
/LINENUMBERS, файл плана создается независимо от того,
указано ли его имя в командной строке. В этом случае, если
его имя не специфицировано, оно принимается по умолчанию -
<имя объектного файла>.MAP.
При указании нескольких объектных файлов или библиотек
их имена разделяются символами + .
Если определены не все файлы (но не опущены
посредством лишней запятой, и не специфицирована установка
оставшихся имен по умолчанию указанием символа ;), LINK
входит в диалоговый режим и запрашивает оставшиеся
неопределенными имена через подсказки.
Спецификации имен файлов и опции могут быть заранее
занесены в специальный файл ответа. Имя этого файла с
предшествующим символом @ и указанием пути поиска, если он
нужен, может быть помещено в любом месте ответа на подсказку
или командной строки и трактуется, как если бы содержимое
файла ответа было непосредственно вставлено в это место.
Следует, однако, помнить, что комбинация символов
CARRIAGE-RETURN / LINE-FEED в файле ответа интерпретируется
как ENTER в подсказке или запятая в командном файле.
Общий вид файла ответа:
<имя объектного файла>
[<имя исполнительного файла>]
[<имя файла плана>]
[<имя библиотеки>]
Каждая группа файлов должна задаваться на отдельной
строке, а файлы в группе, если их несколько, должны
разделяться символом + . Если группа не помещается на одной
строке, в последней позиции строки должен стоять признак
продолжения - символ + . В любой строке файла ответа после
символа / могут быть заданы опции LINK.
В файле ответа могут быть опущены компоненты, уже
определенные ответами на подсказки или командной строкой.
При обнаружении в файле ответа симвода ; остаток файла
игнорируется, и оставшиеся неопределенными имена
устанавливаются по умолчанию из приведенного выше списка.
При использовании файла ответа его содержимое выдается
на консоль в форме подсказок. Если определены не все имена,
LINK переходит в диалоговый режим.
Если файл ответа не содержит комбинации символов
CARRIAGE-RETURN / LINE-FEED или символа ; , LINK выдает на
консоль последнюю строку файла и ожидает нажатия ENTER.
Имя каждого файла может сопровождаться информацией о
подоглавлении, содержащем этот файл, иначе поиск исходного
файла или создание выходного файла будет осуществляться в
текущем подоглавлении.
Работа LINK может быть в любой момент прекращена
нажатием клавиш CONTROL-C.
- 17 -
3.3. Опции LINK.
Все опции LINK обозначаются предшествующим символом /
и могут быть сокращены произвольным образом, но так, чтобы
код оставался уникальным среди опций.
Ниже приведены описания всех опций LINK (в скобках
указаны минимальные сокращения):
/HELP (HE) - Выдать список действующих опций.
Эту опцию нельзя использовать
вместе с именем файла.
/PAUSE (P) - Пауза перед записью модуля в
EXE-файл (и после записи в
MAP-файл, если это
предусмотрено). Во время этой
паузы можно при необходимости
переставить дискеты. Если
используется файл VM.TMP, он
должен находиться на той же
дискете, что и EXE-файл.
/EXEPACK (E) - Установить компактную запись
последовательностей одинаковых
бит. Такой EXE-файл имеет
меньший объем и быстрее
загружается в память, но его
нельзя отлаживать при помощи
SYMDEB. Опция дает эффект, если
программа содержит длинные
потоки идентичных битов и
требует большого числа (более
500) перемещений при загрузке.
/MAP (M) - Формировать MAP-файл. Файл
формируется, даже если он не
специфицирован при запуске LINK,
и имеет в этом случае
умалчиваемое имя (п.3.2).
/LINENUMBERS (LI) - Зафиксировать в MAP-файле номера
строк исходного файла. Эта
информация может в дальнейшем
использоваться MAPSYM и SYMDEB.
Запись номеров строк будет
производиться, если создается
MAP-файл и объектный модуль
содержит данные о строках
исходного текста. Компиляторы
FORTRAN и PASCAL (версии 3.0 и
- 18 -
выше) и C (версии 2.0 и выше)
такие данные автоматически
формируют; в MASM это не
предусмотрено. Если MAP-файл не
специфицирован, его можно
создать принудительно, указав
описываемую опцию в подсказке на
этот файл.
/NOIGNORECASE (NOI) - Установить различие между
строчными и заглавными буквами.
Различие может быть установлено
также опциями /ML и /MX MASM.
/NODEFAULTLIBRARYSEARCH - Игнорировать умалчиваемые
(NOD) библиотеки, ссылки на которые
содержатся в объектном модуле
(их туда помещают компиляторы
языков высокого уровня).
Используются только библиотеки,
специфицированные при запуске
LINK.
/STACK:<число> (ST) - Установить размер стека (в
байтах). Информация о размере
стека, содержащаяся в объектном
модуле, игнорируется. Размер
стека может быть задан в виде
десятичного, 8-ричного (с
предшествующим 0) или 16-ричного
(с предшествующими 0 и x на
малом регистре) числа в пределах
от 1 до 65535. Размер стека
может быть изменен утилитой
EXEMOD.
/CPARMAXALLOC:<число> - Установить максимальное число
(C) 16-байтных параграфов,
необходимых при загрузке
программы в память. Обычно LINK
устанавливает максимальное число
параграфов - 65535.
Указание этой опции позволяет
более эффективно использовать
память. Число параграфов может
быть задано в виде десятичного,
8-ричного (с предшествующим 0)
или 16-ричного (с
предшествующими 0 и x на малом
регистре) числа в пределах от 1
до 65535. Если число параграфов
недостаточно для размещения
программы, LINK наращивает его
до минимально подходящего. Число
параграфов может быть изменено
- 19 -
утилитой EXEMOD. Кроме
размещения программы, опция
может понадобиться для команды !
SYMDEB.
/HIGH (H) - Установить адрес начала
программы на наивысший возможный
адрес свободной памяти. Без этой
опции установка осуществляется
на минимальный возможный адрес.
/DSALLOCATE (D) - Обработать группу с именем
DGROUP. Обычно LINK присваивает
младшему байту группы смещение
0000h. При задании этой опции
старшему байту группы с именем
DGROUP присваивается смещение
FFFFh. В результате данные будут
размещаться в областях программы
с максимально большими адресами.
Опция /D обычно применяется
вместе с опцией /H для более
эффективного использования
незанятой памяти до старта
программы. LINK предполагает,
что все свободные байты в DGROUP
занимают память непосредственно
перед программой. Для
использования группы необходимо
загрузить в регистр сегмента
адрес начала DGROUP.
/NOGROUPASSOCIATION - Игнорировать группы при
(NOG) присвоении адресов элементам
данных и кода. Опция введена для
совместимости с ранними версиями
компиляторов FORTRAN и PASCAL
(версии MICROSOFT 3.13 и ранее и
IBM до 2.0). Не рекомендуется
использовать эту опцию в других
целях.
/OVERLAYINTERRUPT:<число> - Установить номер прерывания при
(O) загрузке оверлейного модуля.
Указанное число замещает номер
стандартного оверлейного
прерывания (03Fh). Номер может
быть задан в виде десятичного,
8-ричного (с предшествующим 0)
или 16-ричного (с
предшествующими 0 и x на малом
регистре) числа в пределах от 0
до 255. MASM не способствует
созданию оверлейных программ.
Поэтому только при помощи опции
- 20 -
/O ассемблерные модули могут
быть включены в оверлейные
программы на языках высокого
уровня, компиляторы которых
подерживают оверлей. Не
рекомендуется устанавливать
номер, совпадающий с каким-либо
другим прерыванием.
/SEGMENTS:<число> (SE) - Установить максимальное число
сегментов, которое может
обработать LINK. Число может
быть задано в десятичной,
8-ричной (с предшествующим 0)
или 16-ричной (с предшествующими
0 и x на малом регистре) форме в
пределах от 1 до 1024. При
отсутствии спецификации опции
полагается 128. Память
выделяется с учетом этого
максимального числа сегментов.
/DOSSEG (DO) - Упорядочить сегменты в
EXE-файле. При спецификации этой
опции сегменты располагаются в
следующей последовательности:
- сегменты с классом CODE;
- другие сегменты, не входящие
в группу DGROUP;
- сегменты, входящие в DGROUP.
Обычная последовательность
сегментов при отсутствии /DO
описана в п.3.4.3.
3.4. Особенности работы LINK.
LINK создает исполнительный файл путем конкатенации
кода программы и сегментов данных, соответствующих
корректным инструкциям исходного текста. Эта сцепленная
форма сегментов и является тем "исполнительным
представлением", которое непосредственно копируется в память
при загрузке программы.
Частично управлять редактированием программных
сегментов можно заданием атрибутов в директиве SEGMENT или
использованием директивы DGROUP для формирования группы
сегментов. Эти директивы определяют целую группу ассоциаций,
классов и типов выравнивания, а также определяют порядок и
относительные начальные адреса сегментов программы. Эта
информация является дополнительной к той, которая задается
опциями LINK.
- 21 -
3.4.1. Выравнивание сегментов.
Для установки начального адреса сегмента LINK
использует задаваемый директивой SEGMENT тип выравнивания:
BYTE, WORD, PARA или PAGE. Эти ключевые слова обеспечивают
выравнивание начала сегмента соответственно по границе
байта, слова (2 байта), параграфа (16 байтов) или страницы
(256 байтов). По умолчанию используется тип PARA.
Байты, пропускаемые из-за выравнивания, заполняются
двоичными нулями.
3.4.2. Номер кадра.
Вычисляемый LINK начальный адрес сегмента зависит от
типа выравнивания сегмента и размеров уже скопированных в
исполнительный файл сегментов.
Этот адрес состоит из смещения и канонического номера
кадра. Канонический адрес кадра определяет адрес первого
параграфа в памяти, содержащего один или более байтов
сегмента. Номер кадра всегда кратен 16. Смещением является
расстояние в байтах от начала параграфа до первого байта
сегмента.
Для типов PAGE и PARA смещение всегда нулевое, а для
типов BYTE и WORD может быть ненулевым.
Номер кадра может быть получен из MAP-файла. Его
содержат первые 5 16-ричных цифр start-адреса сегмента.
3.4.3. Последовательность сегментов.
LINK копирует сегменты в исполнительный файл в той же
последовательности, в какой он их считывает из объектных
файлов.
Сегменты, имеющие идентичные имена классов, считаются
принадлежащими к одному типу классов и копируются в
исполнительный файл как непрерывный блок.
Порядок загрузки сегментов и способы управления этим
порядком путем присваивания типов классов обсуждаются в
п.3.4.3 MICROSOFT MACRO ASSEMBLER REFERENCE MANUAL.
- 22 -
3.4.4. Комбинированные сегменты.
Для определения того, будут ли два или более сегмента,
имеющие одно и то же имя, соединены в один большой сегмент,
LINK использует комбинации типов сегментов. В языке
ассемблера имеются следующие типы комбинаций: PUBLIC, STACK,
COMMON, MEMORY, AT и PRIVATE (п.3.4.2 MICROSOFT MACRO
ASSEMBLER REFERENCE MANUAL).
Если сегмент имеет тип комбинации PUBLIC, LINK
автоматически соединяет его с другими сегментами, имеющими
то же имя и принадлежащими к тому же классу. При соединении
сегментов предполагается, что сегменты непрерывны и все
адреса в сегментах доступны через смещение относительно
адреса кадра. Результат получается таким же, как если бы
полученный большой сегмент был определен в исходном файле
сплошным куском.
LINK сохраняет тип выравнивания каждого сегмента. Это
означает, что, хотя сегменты и включены в один большой
сегмент, код и данные сегментов сохраняют свои типы
выравнивания.
Если размеры соединяемых сегментов превышают 64К,
выдается сообщение об ошибке.
Если сегмент имеет тип комбинации STACK, LINK
выполняет ту же операцию, что и в случае PUBLIC. Различие
заключается в том, что для STACK-сегментов в исполнительный
файл записывается начальное значение указателя стека,
которое представляет собой смещение от конца первого по
порядку сегмента стека или комбинированного сегмента стека.
В этом случае при использовании типа STACK для сегментов
стека программисту нет необходимости предусматривать в
программе загрузку регистра SS.
Если сегмент имеет тип комбинации COMMON, LINK
автоматически соединяет его с другими сегментами, имеющими
то же имя и принадлежащими к тому же классу. Однако, когда
LINK соединяет общие сегменты, начало каждого сегмента
устанавливается на один адрес, в результате чего образуются
серии перекрывающихся сегментов. В итоге получается один
сегмент, который по длине не превышает самый длинный из
комбинируемых сегментов.
Сегменты с типом комбинации MEMORY трактуется LINK в
точности так же, как и PUBLIC-сегменты. MASM обеспечивает
тип MEMORY для совместимости с линкерами, выделяющие MEMORY
как особый тип комбинации.
Сегмент имеет тип комбинации PRIVATE в том случае,
когда в исходном файле нет точных указаний относительно его
типа комбинации. LINK не объединяет PRIVATE-сегменты.
- 23 -
3.4.5. Группы.
Объединение нескольких сегментов в группу позволяет
адресовать их относительно одного адреса кадра. При этом
неважно, принадлежат ли эти сегменты к одному классу. Когда
LINK обнаруживает группу, он соответствующим образом
перестраивает все адресные ссылки в ней.
Сегменты в группе не являются смежными, не принадлежат
к одному классу и имеют разные типы комбинации. Но суммарный
объем всех сегментов в группе не должен превышать 64К.
Группы не влияют на порядок загрузки сегментов в
память. Даже если используются имена классов и объектные
файлы вводятся в соответствующей последовательности, нет
гарантии, что сегменты будут смежными. На практике LINK
может поместить не принадлежащий группе сегмент в те же 64К
памяти.
Хотя в LINK и нет строгой проверки того, помещаются ли
все сегменты группы в 64К памяти, при обнаружении нарушения
этого условия будет выдано сообщение о переполнении
согласования.
3.4.6. Согласования.
Когда в процессе работы LINK уже известны адреса всех
сегментов программы и организованы все комбинации сегментов
и группы, линкер имеет возможность "согласовать" некоторые
неразрешенные ссылки к меткам и переменным. Для этого LINK
вычисляет соответствующие адрес сегмента и смещение и
замещает временные значения, сгенерированные ассемблером, на
новые значения.
В соответствии с типами ссылок LINK реализует
следующие типы согласований:
1. Короткие.
2. Внутренние относительно себя.
3. Внутренние относительно сегмента.
4. Длинные.
Размер вычисляемого значения зависит от типа ссылки.
Если LINK обнаруживает ошибку в предсказанном размере
ссылки, выдается сообщение о переполнении согласования. Это
может произойти, например, когда программа пытается
использовать 16-битовое смещение для доступа к инструкции в
сегменте, имеющем другой адрес кадра. Это же сообщение может
быть выдано, если все сегменты в группе не помещаются внутри
блока памяти в 64К.
Короткая ссылка имеет место в инструкции JMP,
передающей управление на помеченную инструкцию в том же
сегменте или группе, отстоящую от JMP не более, чем на 128
байтов. Для такой ссылки LINK вырабатывает 8-битовое число
со знаком. Если инструкция, на которую передается
- 24 -
управление, находится в другом сегменте или группе, т.е.
имеет другой адрес кадра, или отстоит более, чем на 128
байтов в любом направлении, формируется сообщение об ошибке.
Внутренняя относительно себя ссылка имеет место в
инструкциях, адресующих данные относительно того же сегмента
или группы. Для такой ссылки LINK формирует 16-битовое
смещение. Если данные не принадлежат тому же сегменту или
группе, выдается сообщение об ошибке.
Внутренняя относительно сегмента ссылка имеет место в
инструкциях, адресующих данные в определенном сегменте или
группе или относительно указанного регистра сегмента. Для
этой ссылки LINK вырабатывает 16-битовое смещение. Если
это смещение внутри специфицированного кадра оказывается
больше 64К или меньше 0 или если начало канонического кадра,
содержащего требуемые данные, неадресуемо, выдается
сообщение об ощибке.
Длинная ссылка имеет место в инструкциях CALL,
передающих управление в другой сегмент или группу. LINK в
этом случае вырабатывает 16-битовый адрес кадра и 16-битовое
смещение. Если вычисленное смещение больше 64К или меньше 0
или если начало канонического кадра, в который передается
управление, неадресуемо, формируется сообщение об ошибке.
3.4.7. Поиск библиотек.
Процедура поиска библиотеки, иногда требуемой для
разрешения внешних ссылок, обладает некоторыми
особенностями. Если путь поиска указан вместе с именем
библиотеки в командной строке, поиск осуществляется только
там. Если же путь явно не указан, поиск производится в
следующей последовательности:
1. В текущем подоглавлении.
2. Если в командной строке заданы один или несколько
путей поиска для других библиотек, LINK
просматривает их в порядке следования в строке.
3. На путях, определенных переменной LIB команды DOS
SET. При помощи команды SET могут быть заданы
несколько путей поиска, разделяемых точкой с
с запятой. Вид команды SET:
SET LIB=<список путей>
© KOAP
Open Portal 2000
|