Многоэтапная обработка пользовательской программы
Стр 1 из 2Следующая ⇒ ЛЕКЦИЯ 15. УПРАВЛЕНИЕ ПАМЯТЬЮ Основные положения размещения процессов в памяти
Любая программа, введенная в систему, должна быть размещена в памяти и оформлена в виде процесса для ее выполнения. Каждая программа при вводе в систему помещается во входную очередь – совокупность процессов на диске, ожидающих размещения в памяти для выполнения своих программ. До своего выполнения пользовательские программы проходят в системе несколько стадий. Связывание программ и данных с адресами в памяти
Перед загрузкой данных или кода в память они должны быть в какой-либо момент связаны с определенными адресами в памяти. Связывание может выполняться на разных этапах: · Связывание во время компиляции (compile-time). Если адрес в памяти априорно известен, компилятором может быть сгенерирован код с абсолютными адресами. При любом изменении размещения программы в памяти должна быть выполнена перекомпиляция. Данный подход более характерен для ранних компьютерных систем с небольшим объемом памяти, либо для обработки и выполнения системных модулей – частей ядра ОС, для которых характерно использование резидентных абсолютных адресов. Для пользовательских программ такой подход неудобен, так как не обеспечивает достаточной гибкости, в частности, возможности без изменений перезагрузить код в другую область памяти. · Связывание во время загрузки (load-time). Загрузка программы в память – стадия ее обработки системой, предшествующая выполнению программы. Чтобы начальный адрес области памяти, куда загружается программа, можно было менять, и это не привело бы к необходимости изменения кода программы, применяется следующий метод. Генерируется перемещаемый код (relocatable code) – код, в котором адресация происходит относительно значения регистра перемещения (relocation register),и адрес в памяти равен сумме значения регистра перемещения и адреса, вычисляемого в команде. Таким образом, при необходимости загрузки кода на другое место в памяти требуется изменить только значение регистра перемещения. Подобный подход широко используется для программ, написанных на традиционных языках программирования.
· Связывание во время исполнения (runtime),или динамическое (позднее) связывание. Используется, если процесс во время выполнения может быть перемещен из одного сегмента памяти в другой. Для реализации связывания во время исполнения требуется аппаратная поддержка отображения адресов – например, регистры базы и границы. В большинстве систем для пользовательских программ используется, главным образом, именно связывание во время исполнения. Многоэтапная обработка пользовательской программы
Чтобы лучше представлять себе все детали адресации и размещения программы в памяти, рассмотрим общую схему многоэтапной обработки пользовательской программы, используемую в любой ОС. Исходный код программы (в форме текстового файла) на языке высокого уровня или на ассемблере преобразуется компилятором или ассемблером в объектный модуль, содержащий бинарные выполняемые машинные команды и таблицу символов, определенных и использованных в данном модуле кода. Рассмотренная фаза называется временем компиляции. Однако объектный модуль не может непосредственно исполняться, так как он содержит неразрешенные ссылки на внешние модули и их компоненты. Следующая фаза обработки программы – редактирование связей. Редактор связей (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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|