Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_ОПЕРАЦИОННЫЕ СИСТЕМЫ.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
642.56 Кб
Скачать

3.7. Сборка программ

В большинстве современных языков программирования программа состоит из отдельных слабо связанных модулей. Как правило, каждому такому моду­лю соответствует отдельный файл исходного текста. Эти файлы независимо обрабатываются языковым процессором (компилятором), и для каждого из них генерируется отдельный файл, называемый объектным модулем. Затем, запускается программа, называемая редактором связей, компоновщиком или, линкером (linker — тот, кто связывает), которая формирует из заданных объектных модулей цельную программу.

Объектный модуль отчасти похож по структуре на перемещаемый загрузочный модуль. Дело в том, что сборку программы из нескольких модулей; можно уподобить загрузке в память нескольких программ. При этом возникает та же задача перенастройки адресных ссылок, что и при загрузке относительного загрузочного файла . Поэтому объектный модуль должен в той или иной форме содержать таблицу перемещений.

Кроме ссылок на собственные метки, объектный модуль имеет право ссылаться на символы, определенные в других модулях.

Для разрешения внешних ссылок мы должны создать две таблицы: в одной перечислены внешние объекты, на которые ссылается модуль, в другой — объекты, определенные внутри модуля, на которые можно ссылаться извне. Обычно с каждым таким объектом ассоциировано имя, называемое глобаль­ным символом. Как правило, это имя совпадает с именем соответствующей Функции или переменной в исходном языке.

Типичный объектный модуль содержит следующие структуры данных.

Таблицу перемещений, т. е. таблицу ссылок на перемещаемые объекты внутри модуля.

Таблицу ссылок на внешние объекты. Иногда это называется таблицей или списком импорта.

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

Различную служебную информацию, такую, как имя модуля, программу, которая его создала и отладочную информацию.

Собственно код и данные модуля.

Как правило, код и данные разбиты на именованные секции. Например, в системах семейства Unix программы, написанные на языке С, состоят из минимум трех программных секций:

. text — исполняемый код (современные компиляторы иногда помещают в эту секцию и данные, описанные как const);

.data — статически инициализированные данные;

.bss — неинициализированные данные.

Некоторые форматы объектных модулей, в частности ELF (Executable and Linking Format — формат исполняемых и собираемых [модулей], используе­мый современными системами семейства Unix), предоставляют особый тип глобального символа — слабый (weak) символ.

3.8. Объектные библиотеки

Крупные программы часто состоят из сотен и тысяч отдельных модулей. Кроме того, существуют различные пакеты подпрограмм, также состоящие из большого количества модулей. Один из таких пакетов используется прак­тически в любой программе на языке высокого уровня — это так называе­мая стандартная библиотека. Для решения проблем, возникающих при под­держании порядка в наборах из большого количества объектных модулей, были придуманы библиотеки объект­ных модулей.

Библиотека, как правило, представляет собой последовательный файл, со­стоящий из заголовка, за которым последовательно располагаются объект­ные модули. В заголовке содержится следующая информация.

Список всех объектных модулей, со смещением каждого модуля от нача­ла библиотеки. Смещение нужно для того, чтобы можно было легко най­ти требуемый модуль.

Список всех глобальных символов, определенных в каждом из модулей, с указанием, в каком именно мо­дуле он был определен.

Линкер обычно собирает в программу все объектные модули, которые были ему, заданы в ко­мандной строке, даже если на этот модуль не было ни одной ссылки. С библиотечными модулями он ве­дет себя несколько иначе.

Встретив ссылку на глобальный символ, компоновщик ищет опре­деление этого символа во всех мо­дулях, которые ему были заданы. Если там такого символа нет, то линкер ищет этот символ в заголов­ке библиотеки. Если его нет и там, компоновщик сообщает: "Не опре­делен символ SYMBOL", — и за­вершает работу. Некоторые редак­торы связей, правда, могут продолжить работу и даже собрать загружаемый модуль, но, как правило, таким модулем пользоваться нельзя, так как в нем содержится ссылка на некорректный адрес. Если же определение символа библиотеке есть, компоновщик "вытаскивает" соответствующий модуль и дальше работает так, будто этот модуль был задан ему наравне с остальными объектными файлами. Этот процесс повторяется до тех пор, пока не будут разрешены все глобальные ссылки, в том числе и те, которые возникли библиотечных модулях, или пока не будет обнаружен неопределенный сим­вол. Благодаря такому алгоритму в программу включаются только те модуль из библиотеки, которые нужны.

В системах семейства Unix библиотеки такой структуры называются архив ними библиотеками, чтобы отличить их от разделяемых библиотек.