Реклама:

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

На рис. 7.5 показано, что произойдет, если уже распределенная в памяти программа (см. рис. 7.4, б) будет загружена по адресу 400, а не по адресу 100, куда ее изначально поместил компоновщик. Все адреса памяти оказываются неправильными, и это при отсутствии какой-либо информации о распределении памяти. Даже если эта информация была бы доступна, перераспределять все адреса при каждой загрузке программы было бы расточительно.

Проблема перемещения программ, уже скомпонованных и размещенных в памяти, имеет непосредственное отношение к моменту окончательного связывания символических имен с абсолютными адресами физической памяти. В программе содержатся символические имена для адресов памяти (например, В1* 1_). Время, в которое определяется адрес в основной памяти, соответствующий имени Ц называется временем связывания. Существует по крайней мере шесть вариантов времени связывания:

1. Когда программа пишется.

2. Когда программа транслируется.

3. Когда программа компонуется, но еще до загрузки.

4. Когда программа загружается.

5. Когда загружается базовый регистр, который используется для адресации.

6. Когда выполняется команда, содержащая требуемый адрес.

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

Здесь возникает два вопроса. Во-первых, когда символические имена связываются с виртуальными адресами? Во-вторых, когда виртуальные адреса связываются с физическими адресами? Только после двух этих операций процесс связывания можно считать завершенным. Когда компоновщик объединяет отдельные адресные пространства объектных модулей в единое линейное адресное пространство, он фактически создает виртуальное адресное пространство. Перераспределение в памяти и компоновка нужны для связывания символических имен с определенными виртуальными адресами. Это верно независимо от того, используется виртуальная память или нет.

Предположим, что адресное пространство, изображенное на рис. 7.4, б, было разбито на страницы. Ясно, что виртуальные адреса, соответствующие символическим именам А, В, Си Д уже определены, хотя их физические адреса будут зависеть от содержания таблицы страниц. Реально связывание символических имен с виртуальными адресами происходит в исполняемом двоичном коде.

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

Второй механизм - применение регистра перераспределения времени исполнения. Компьютер CDC 6600 и его последователи содержали такой регистр. В машинах, в которых используется эта технология перераспределения памяти, регистр всегда указывает на физический адрес начала текущей программы. Ап-паратно этот регистр добавляется ко всем адресам перед их распределением в памяти. Весь процесс перераспределения памяти является прозрачным для пользовательских программ. Пользовательские программы даже не подозревают, что происходит перераспределение памяти. Если программа перемещается, операционная система должна обновить регистр перераспределения. Такой механизм менее распространен, чем разбиение на страницы, поскольку перемещаться должна вся программа целиком (если есть отдельные регистры перераспределения для кода и данных, как, например, в процессоре Intel 8088, то объектами перемещения будут обе части программы).

Время компоновки и динамическое перераспределение памяти

Рис. 7.5. Исполняемая программа с рис. 7.4, б, сдвинутая вверх на 300 адресов. Многие команды теперь обращаются по неправильным адресам памяти

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

Структура объектного модуля || Оглавление || Динамическая компоновка