Информатика и технология программирования


СвязываниеВнешние ссылки и точки входа - часть 2


На заключительном этапе трансляции программа -компоновщик (линкер), составляет из объектных модулей загрузочный модуль программы (исполняемый программный файл), производя при этом следующие действия:



-составление загрузочного модуля из двоичных данных объектных модулей с определением начального адреса каждого объектного модуля в файле (компоновка);



-связывание внешних ссылок и соответствующих точек входа (редактирование связей);



-подключение необходимых объектных модулей из библиотек с выполнением над ними вышеуказанных действий.

Рассмотрим подробнее алгоритм работы компоновщика:



-двоичные данные объектных модулей размещаются в загрузочном модуле друг за другом, так что каждый модуль получает в нем свой начальный адрес. Если объектный модуль имеет точку входа, то ее адрес теперь складывается из начального (абсолютного) адреса модуля и собственного (относительного) адреса точки входа;



-для каждой внешней ссылки ищется точка входа с таким же именем. Если она найдена, то ее адрес в загрузочном модуле подставляется на место внешней ссылки;



-если в загрузочном модуле остаются неразрешенные внешние ссылки, для которых не нашлось соответствующих точек входа, то компоновщик просматривает указанные библиотеки;



-библиотека представляет собой файл, в котором объединены несколько обычных объектных модулей (с общим каталогом в начале). Если в одном из объектных модулей компоновщик находит необходимую точку входа, то он читает весь объектный модуль и размещает его в загрузочном модуле программы. Затем повторяются действия по связыванию внешних ссылок и точек входа;



-объектные модули из библиотек могут в свою очередь содержать внешние ссылки к другим объектным модулям как в собственной, так и других библиотеках, поэтому процесс компоновки является итерационным.



.


Исходные модули Объектные модули
a.c pp a.obj
extern double f(); 0000
double g() {} 1000 код функции g()
... внешняя ссылка
f(); 2000 CALL (0000) "f"
g(); 300 0 CALL 1000
4000
b.c pp b.obj
double f() { 1200 точка входа f=1200
код функции f()
... внешняя ссылка
printf("%d",n); 1400 CALL (0000) "printf"
} код функции f()
1600

.


Загрузочный модуль a.exe

.


0000 a.obj
1000 код функции g()
внешняя ссылка
2000 CALL (5200) - адрес точки входа f
3000 CALL 1000
4000 b.obj
5200 Точка входа f= 4000 + 1200 = 5200
код функции f()
внешняя ссылка
5400 CALL (6600) - адрес точки входа printf
код функции f()
5600 библиотечный модуль
Точка входа printf = 1000 + 5600 = 6600
6600 Код функции printf




Начало  Назад  Вперед