I. Элементы архитектуры вычислительных систем

Вид материалаДокументы
Подобный материал:
1   ...   5   6   7   8   9   10   11   12   ...   42


Как следует из вышеизложенного, подготовка программы к выполнению сопряжена со следующими взаимосвязанными процессами:
  1. Загрузкой, обеспечивающей размещение программы в оперативной памяти для исполнения.
  2. Перемещением, которое позволяет модифицировать объектную программу так, что она может загружаться с адреса, отличного от первоначально заданного.
  3. Связыванием, обеспечивающим объединение двух и более отдельно оттранслированных объектных программ и предоставляющим информацию, необходимую для разрешения ссылок между ними.

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

Системная программа, выполняющая загрузку называется загрузчиком. Многие загрузчики обеспечивают, кроме того, перемещение и связывание.

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

Загрузчики, обеспечивающие перемещение программ называются перемещающими или относительными загрузчиками (relocating/relative loaders).

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

Основное отличие между редактором связей и связывающим загрузчиком иллюстрирует рис.3.1.



Рис.3.1. Обработка объектной программы с использованием связывающего загрузчика и редактора связей

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

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

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

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

Среди современных ОС довольно много систем, использующих тот или иной способ сборки при загрузке (связывающий загрузчик). Таким образом устроена, например, Novell Netware. Таким же образом организован ряд систем реального времени, таких как OS-9 или VxWorks. Сборка при загрузке существенно замедляет процесс загрузки программы, но упрощает, с одной стороны, разделение кода, а с другой стороны - разработку программ.

В системах MS Windows и OS/2 используется способ загрузки, промежуточный между сборкой в момент загрузки и сборкой заранее. Загрузочный модуль в этих системах может быть полностью самодостаточным, а может содержать ссылки на другие модули, называемые DLL (Dynamically Loadable Library - динамически загружаемая библиотека). Самое хорошее в этой схеме то, что модуль, по собственному желанию, может выбирать различные библиотеки. Единственное ограничение состоит в том, что такие библиотеки обязаны быть совместимыми по вызовам.

Например, программа CorelDRAW! может импортировать и экспортировать изображения в различных видах, начиная от собственного внутреннего формата .CDR или Windows Bitmap, и кончая сильноупакованным форматом Jpeg или специализированными форматами, вроде Targa-файлов. Импорт и экспорт каждого формата выполняется отдельной DLL.

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

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

Кроме того, использование DLL сильно замедляет процесс загрузки программ и несколько снижает общую производительность систем с виртуальной памятью. Системы семейства Unix использующие монолитный загрузочный модуль и/или разделяемые библиотеки, заметно быстрее, чем OS/2 и Windows NT, использующие DLL.

3.2 

Управление оперативной памятью