Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО юнита 2.doc
Скачиваний:
38
Добавлен:
17.11.2019
Размер:
5.82 Mб
Скачать

3.5 Создание и определение имен при редактировании связей

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

Виды операторов присваивания:

– с символом . в левой части – для управления счетчиком размещения;

– с символом . в правой части – для присваивания имени настраиваемого значения;

– без символа . – для присваивания имени абсолютного значения.

В операторах второго вида имени присваивается адрес, который становится известным только после размещения.

Значение выражения, содержащего счетчик размещения, вычисляется в процессе размещения, поэтому такие выражения могут встречаться только внутри предложений SECTIONS. В предложе-ниях SECTIONS могут быть и операторы присваивания, не содержащие точку, хотя обычно так не делается. Значения выражений из правых частей таких операторов определяются после окончания размещения. Изменять подобным образом адрес какого-либо имени опасно. Например, имя определено в секции .data, где для него отведен и проинициализирован некоторый участок памяти. Если редактируется ряд объектных файлов, содержащих ссылки на это имя, соответствующий ему элемент таблицы имен с момента присваивания будет отражать новый, измененный адрес этого имени. Инициализированные данные не переписываются по новому адресу. ld(1) выдает предупреждение при изменении значения каждого имени, ранее уже определенного.

3.6 Размещение секций в именованных областях памяти

Можно потребовать, чтобы секция была размещена где-либо внутри именованной области памяти, определенной ранее предложением MEMORY. По аналогии с принятым в операционной системе UNIX синтаксисом переназначения стандартного вывода для этого применяется символ >. Пример:

MEMORY {

mem1: o=0x000000 l=0x10000

mem2 (RW): o=0x020000 l=0x40000

mem3 (RW): o=0x070000 l=0x40000

mem1: o=0x120000 l=0x04000

}

SECTIONS {

outsec1: {f1.o (.data)} > mem1

outsec2: {f2.o (.data)} > mem3

}

Эти предложения предписывают ld(1) разместить секцию outsec1 где-либо внутри области памяти mem1, то есть между 0x0 и 0xFFFF или между 0x120000 и 0x123FFF. Секция outsec2 будет размещена в диапазоне адресов от 0x70000 до 0xAFFFF.

3.7 Инициализация пустот и секций .Bss

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

Пустоты, а равно и выходные секции .bss, можно заполнить произвольными двухбайтными значениями, указав опцию инициализации в предложении SECTIONS. Опция инициализации воздействует только на пустоты и секции .bss. Опция может понадобиться, например, если необходимо заполнить определенным образом таблицу неинициализированных данных без перекомпиляции программ или если нужно заполнить "дыру" в секции .text командами перехода к подпрограмме обработки ошибок.

Потребовать инициализации можно как для выходной секции в целом, так и для отдельной ее части. Однако в связи с тем, что неинициализированная секция .bss физически не занимает места в выходном файле, ее нельзя проинициализировать частично. Даже если заказана инициализация только части секции .bss, она будет проинициализирована целиком. Если секция .bss объединяется с секциями .text или .data или инициализируется часть секции .bss, то произойдет одно из двух:

– если опция инициализации задана, она будет отнесена ко всем частям выходной секции, полученным из входных секций .bss и не имеющим явной инициализации;

– если опция инициализации не задана, ld(1) заполнит то же место подразумеваемым запол-нителем.