Многоэтапная обработка пользовательской программы

Чтобы лучше представлять себе все детали адресации и размещения программы в памяти, рассмотрим общую схему многоэтапной обработки пользовательской программы, используемую в любой ОС. Схема представлена на рис. 15.1.


Рис. 15.1. Многоэтапная обработка пользовательской программы.

Исходный код программы (в форме текстового файла) на языке высокого уровня или на ассемблере преобразуется компилятором или ассемблером в объектный модуль, содержащий бинарные выполняемые машинные команды и таблицу символов, определенных и использованных в данном модуле кода. Рассмотренная фаза называется временем компиляции.

Однако объектный модуль не может непосредственно исполняться, так как он содержит неразрешенные ссылки на внешние модули и их компоненты. Следующая фаза обработки программы – редактирование связей. Редактор связей (linker) – системная программа, которая получает на вход один или несколько объектных модулей, а на выходе выдает загрузочный модуль – двоичный код, образованный кодом нескольких объектных модулей, в котором разрешены все межмодульные ссылки - для каждого символа, внешнего для данного объектного модуля A, найден соответствующий символ (процедуры, переменной и т.д.) из другого модуля B, на который ссылается модуль A, и код соответственно откорректирован, т.е. он правильно адресует внешний символ.

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

Фаза вызова редактора связей и загрузчика носит общее название время загрузки. Во многих ОС функции редактора связей и загрузчика, с целью экономии времени обработки программы в системе, объединены в одной системной программе – редакторе связей и загрузчике (linker and loader). Например, в системе UNIX редактор связей и загрузчик называется ld (Linker and loaDer). Объединенному загрузчику и редактору связей на вход передается список объектных модулей и список библиотек, и в результате он генерирует исполняемый код. Фаза редактирования связей и загрузки часто на программистском слэнге называется линковкой (linking). Будем далее использовать именно этот короткий и выразительный термин.

Вот пример последовательности фаз обработки программы в терминах команд системы UNIX:

сс –c program.c // Компиляция исходного кода на Си.

// В рабочей директории – объектный модуль program.o

ld program.o mylibrary.a // редактирование связей и загрузка

// В рабочей директории – исполняемый код с именем по умолчанию a.out

a.out // Исполнение программы

// В стандартный вывод (по умолчанию – на консоль)

// выдаются результаты программы

В примере предполагается, что в файле program.c хранится исходный код программы на Си, которая использует библиотечные функции из библиотеки mylibrary.a. Отметим соглашения в системе UNIX о расширениях имен файлов: .c – исходный код на Си, .o – объектный модуль, .a – бинарный файл статически линкуемой библиотеки (аббревиатура от термина archive). Исполняемый код (executable) в UNIX не имеет стандартного расширения имени, но имеет полное имя по умолчанию – несколько архаичное имя a.out (аббревиатура от asembler output).

В Windows соглашения о расширениях имен файлов несколько иные: .obj – объектный модуль, .exe – исполняемый код, .lib – статически линкуемая библиотека.

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

На этапе выполнения, при первом обращении к ним из программы, в память загружаются динамически линкуемые библиотеки (dymanically linked libraries). Данная разновидность библиотек, реализованная во всех современных ОС, позволяет сэкономить память, занимаемую образом исполняемого кода, который при статической линковке с библиотеками оказывается очень велик. Подробнее об этом – позже в данной лекции.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: