2015-03-26 2 views
3

Что касается AT (...) директивы для ld, this source состояний:В чем разница между «адресом загрузки» и «адресом перемещения»?

AT (ldadr) The expression ldadr that follows the AT keyword specifies the load address of the section. The default (if you do not use the AT keyword) is to make the load address the same as the relocation address. This feature is designed to make it easy to build a ROM image.

Я искал, но не нашел четкое определение того, что подразумевается под «адресом загрузки» и «переселение адрес».

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

Как влияет результат компоновщика, если эти два адреса различны?

ответ

1

Разница имеет решающее значение. Адрес пересылки добавляется ко всем релокам в разделе. Поэтому, если он отличается от адреса загрузки, в этом разделе ничего не будет работать - все релоки внутри раздела будут разрешены к неправильным значениям.

Зачем нам нужна такая техника? Не так много приложений, но предположим, что (from here) у вас есть на вашей архитектуре очень быстрой памяти на 0x1000

Тогда вы можете взять две секции, чтобы иметь перемещение адреса 0x1000:

.text0 0x1000 : AT (0x4000) { o1/*.o(.text) } 
__load_start_text0 = LOADADDR (.text0); 
__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0); 
.text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) } 
__load_start_text1 = LOADADDR (.text1); 
__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1); 
. = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1)); 

Теперь во время выполнения идти вперед и когда вам нужно text1, управлять им самостоятельно, чтобы быть скопирована на правильном адресе от его фактического адреса загрузки:

extern char __load_start_text1, __load_stop_text1; 
memcpy ((char *) 0x1000, &__load_start_text1, 
     &__load_stop_text1 - &__load_start_text1); 

И затем использовать его, , как он был загружен здесь естественно. Этот метод называется наложением.

думаю, пример довольно четкий.

+0

Konstantin, спасибо за ваш пример. Я думаю, что понимаю: все переходы, звонки и т. Д. В связанном коде вычисляются так, как если бы код был загружен на «адрес переадресации», но во время выполнения он фактически загружается на «адрес загрузки»? Таким образом, «адрес загрузки» фактически является смещением в объектном файле, где появляется код? Или объектные файлы (ELF и т. Д.) Содержат директивы, которые указывают загрузчику, куда поместить код в память во время выполнения? –

+0

Чтобы уточнить, что я спрашиваю, как только компоновщик решил «адрес загрузки» для раздела, как это влияет на выходной двоичный файл? –

+0

Да, это часть формата ELF, если вы ориентируетесь на систему UNIX http://www.skyfree.org/linux/references/ELF_Format.pdf –

Смежные вопросы