Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

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




ЛЕКЦИЯ 15. УПРАВЛЕНИЕ ПАМЯТЬЮ

Основные положения размещения процессов в памяти

 

Любая программа, введенная в систему, должна быть размещена в памяти и оформлена в виде процесса для ее выполнения. Каждая программа при вводе в систему помещается во входную очередь – совокупность процессов на диске, ожидающих размещения в памяти для выполнения своих программ. До своего выполнения пользовательские программы проходят в системе несколько стадий.

Связывание программ и данных с адресами в памяти

 

Перед загрузкой данных или кода в память они должны быть в какой-либо момент связаны с определенными адресами в памяти. Связывание может выполняться на разных этапах:

· Связывание во время компиляции (compile-time). Если адрес в памяти априорно известен, компилятором может быть сгенерирован код с абсолютными адресами. При любом изменении размещения программы в памяти должна быть выполнена перекомпиляция. Данный подход более характерен для ранних компьютерных систем с небольшим объемом памяти, либо для обработки и выполнения системных модулей – частей ядра ОС, для которых характерно использование резидентных абсолютных адресов. Для пользовательских программ такой подход неудобен, так как не обеспечивает достаточной гибкости, в частности, возможности без изменений перезагрузить код в другую область памяти.

· Связывание во время загрузки (load-time). Загрузка программы в память – стадия ее обработки системой, предшествующая выполнению программы. Чтобы начальный адрес области памяти, куда загружается программа, можно было менять, и это не привело бы к необходимости изменения кода программы, применяется следующий метод. Генерируется перемещаемый код (relocatable code) – код, в котором адресация происходит относительно значения регистра перемещения (relocation register),и адрес в памяти равен сумме значения регистра перемещения и адреса, вычисляемого в команде. Таким образом, при необходимости загрузки кода на другое место в памяти требуется изменить только значение регистра перемещения. Подобный подход широко используется для программ, написанных на традиционных языках программирования.

· Связывание во время исполнения (runtime),или динамическое (позднее) связывание. Используется, если процесс во время выполнения может быть перемещен из одного сегмента памяти в другой. Для реализации связывания во время исполнения требуется аппаратная поддержка отображения адресов – например, регистры базы и границы. В большинстве систем для пользовательских программ используется, главным образом, именно связывание во время исполнения.

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

 

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


Рис. 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). Данная разновидность библиотек, реализованная во всех современных ОС, позволяет сэкономить память, занимаемую образом исполняемого кода, который при статической линковке с библиотеками оказывается очень велик. Подробнее об этом – позже в данной лекции.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...