Глава 3. Загрузчики и программы связывания 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Глава 3. Загрузчики и программы связывания



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

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

2. Перемещением, которое позволяет модифицировать объектную программу так, что она может загружаться с адреса, отличного от первоначально заданного (см. разд. 2.2.2).

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

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

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

Как и в предыдущей главе, мы вначале рассмотрим основную функцию изучаемого программного обеспечения - в данном случае загрузку объектной программы в оперативную память для последующего ее исполнения. В разд. 3.1 представлен абсолютный загрузчик (absolute loader). Подобный загрузчик мог бы использоваться для УУМ совместно с ассемблером, описанным в разд. 2.1.

В разд. 3.2 разбираются вопросы перемещения и связывания программ с точки зрения загрузчика. Мы обсудим несколько возможных способов представления объектной программы и исследуем, как они связаны со структурой ЭВМ. Мы также рассмотрим связывающий загрузчик (linking loader), представляющий собой наиболее совершенный тип загрузчика, который используется в большинстве современных вычислительных систем. В разд. 3.3 приведены некоторые из наиболее часто встречающихся свойств загрузчика, которые не имеют прямой связи со структурой машины. Как и прежде, нашей целью является не рассмотрение всех возможных свойств, а изучение концепций и технических приемов, наиболее часто применяемых при создании загрузчиков.

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

Наконец, в разд.3.5 мы вкратце обсудим некоторые примеры реальных загрузчиков и программ связывания. Мы рассмотрим те же машины, для которых в разд. 2.5 были описаны ассемблеры, и укажем на взаимосвязь, существующую между ассемблером и загрузчиком. Как и ранее, мы сосредоточим наше внимание на тех аспектах системных компонент, которые зависят от особенностей аппаратуры или программного обеспечения.

 

Основные функции загрузчика

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

 

H_COPY _001000_00107A T_001000_1E_141033_482039_001036_281030_301015_482061_3C1003_00102A_0C1039_00102D T_00101E_15_0C1036_482061_081033_4C0000_454F46_000003_000000 T_002039_1E_041030_001030_E0205D_30203F_D8205D_281030_302057_549039_2C205E_38203F T_002057_1C_101036_4C0000_F1_001000_041030_E02079_302064_509039_DC2079_2C1036 T_002073_07_382064_4C0000_05

E_001000

a

 

Адрес Содержимое

       
   


0000 хххххххх хххххххх хххххххх хххххххх

0010 xxxxxxxх хххххххх хххххххх хххххххх

.....

.....

.....

0FF0 xxxxxxxх хххххххх хххххххх хххххххх

1000 14103348 20390010 36281030 30101548

1010 20613С10 0300102А 0С103900 102D0С10

1020 36482061 0810334С 0000454F 46000003

1030 000000xx хххххххх хххххххх хххххххх COPY

.....

.....

.....

2030 xxxxxxxх хххххххх хх041030 001030Е0

2040 205D3020 3FD8205D 28103030 20575490

2050 392С205Е 38203F10 10364С00 00F10010

2060 00041030 Е0207930 20645090 39DС2079

2070 2С103638 20644С00 0005хххх хххххххх

2080 xxxxxxxх хххххххх хххххххх хххххххх

.....

.....

.....

 

б

Рис. 3.1. Загрузка абсолютной программы.

 

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

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

 

begin

прочитать запись-заголовок

проверить имя и длину программы

прочитать первую запись тела программы

while тип записи < > 'Е' do

begin

{если объектный код задан в символьном виде, то

преобразовать его во внутреннее представление}

переписать объектный код в заданное место оперативной памяти

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

end

передать управление по адресу, эаданному в занисе-конец

еnd

 

Рис. 3.2. Алгоритм абсолютного загрузчика.

 

Например, машинный код операции для команды STL представляется в виде пары символов 14. Когда они считываются загрузчиком (как часть объектной программы), они будут занимать два байта памяти. Однако в команде, которая загружается для выполнения, этот код операции должен быть записан в одном байте с шестнадцатеричным значением 14. Таким образом, каждая пара байтов объектной программы должна быть упакована во время загрузки в один байт. Очень важно четко понимать, что на рис. 3.1а каждый символ представляет одни байт записи объектной программы. С другой стороны, на рис. 3.1б каждый символ представляет одну шестнадцатеричную цифру (т. е. полбайта).

Данный способ представления объектной программы (Прим. - Напомним, что под объектной программой понимается информация, поступающая загрузчику в качестве исходных данных.) неэффективен как с точки зрения занимаемого объема памяти, так и времени выполнения загрузки. Поэтому в большинстве машин объектные программы хранятся в двоичном представлении, в котором каждый байт объектного кода записывается в виде отдельного байта объектной программы. Конечно, в таком представлении каждой байт может содержать любую двоичную величину. Мы должны быть уверены, что в имеющихся в системе соглашениях по работе с файлами и устройствами не предусмотрено использование каких-либо кодов в качестве управляющих символов. Например, соглашение, описанное в разд. 2.1, в котором в качестве признака конца записи используется байт, содержащий шестнадцатеричное значение 00, очевидно, не подходит для представления объектной программы в двоичном виде.

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

 



Поделиться:


Последнее изменение этой страницы: 2017-02-17; просмотров: 272; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.148.102.90 (0.015 с.)