Почему вы не попробовали?
hello:
.long .
.long 0x11111111
.long 0x22222222
.long 0x33333333
.long 0x44444444
.long 0x55555555
.long 0x66666666
.globl TEST
TEST:
adr r0,hello
bx lr
связаны между собой и разобраны
0000803c <hello>:
803c: 0000803c andeq r8, r0, r12, lsr r0
8040: 11111111 tstne r1, r1, lsl r1
8044: 22222222 eorcs r2, r2, #536870914 ; 0x20000002
8048: 33333333 teqcc r3, #-872415232 ; 0xcc000000
804c: 44444444 strbmi r4, [r4], #-1092 ; 0xfffffbbc
8050: 55555555 ldrbpl r5, [r5, #-1365] ; 0xfffffaab
8054: 66666666 strbtvs r6, [r6], -r6, ror #12
00008058 <TEST>:
8058: e24f0024 sub r0, pc, #36 ; 0x24
805c: e12fff1e bx lr
TEST возвращает 0x803C, как мы оба ожидали.
Первый элемент в списке, хотя может быть вашей тайной. Обратите внимание, как они используют ярлык точки, чтобы указать здесь или этот адрес, поэтому первым элементом в списке является адрес начала списка. которые r0 уже могли бы сделать только mov r3, r0, но, возможно, сжигают эту инструкцию, просто загружая ее и сжигая баран с одной инструкцией. кто знает ...
так
.globl TEST
TEST:
adr r0,hello
ldmia r0,{r3}
mov r3,r0
bx lr
который возвращает то же значение 0x803C.
Теперь
.globl TEST
TEST:
adr r0,hello
ldmia r0,{r3}
subs r3,r0,r3
mov r0,r3
bx lr
как и ожидалось, что возвращает ноль, так что смысл всего этого? Обратите внимание, что весь этот раздел не зависит от позиции? Ну, что, если я изменить линкер думать, что это загружается где-то еще ...
MEMORY
{
ram : ORIGIN = 0xA000, LENGTH = 0x1000000
}
продуцирующие
0000a03c <hello>:
a03c: 0000a03c andeq r10, r0, r12, lsr r0
a040: 11111111 tstne r1, r1, lsl r1
a044: 22222222 eorcs r2, r2, #536870914 ; 0x20000002
a048: 33333333 teqcc r3, #-872415232 ; 0xcc000000
a04c: 44444444 strbmi r4, [r4], #-1092 ; 0xfffffbbc
a050: 55555555 ldrbpl r5, [r5, #-1365] ; 0xfffffaab
a054: 66666666 strbtvs r6, [r6], -r6, ror #12
0000a058 <TEST>:
a058: e24f0024 sub r0, pc, #36 ; 0x24
a05c: e8900008 ldm r0, {r3}
a060: e0503003 subs r3, r0, r3
a064: e1a00003 mov r0, r3
a068: e12fff1e bx lr
, но все-таки выполнить в том же месте дает 0xFFFFE000 что -0x2000 из-за направления Я изменил свой компоновщик, если я изменил его на 0x5000 вместо 0xA000. В качестве разницы получается 0x3000.
Так что этот код делает это
.long .
это время компиляции АСПД выполнение и используют во время выполнения ПК так что этот код будет обнаруживая разницу между фактическим адресом памяти, где таблицей является и во время компиляции адрес, где находится таблица. если элементы в таблице времени компиляции адрес
hello:
.long .
.long one
.long two
.long three
one:
.long 0x44444444
two:
.long 0x55555555
three:
.long 0x66666666
0000503c <hello>:
503c: 0000503c andeq r5, r0, r12, lsr r0
5040: 0000504c andeq r5, r0, r12, asr #32
5044: 00005050 andeq r5, r0, r0, asr r0
5048: 00005054 andeq r5, r0, r4, asr r0
0000504c <one>:
504c: 44444444 strbmi r4, [r4], #-1092 ; 0xfffffbbc
00005050 <two>:
5050: 55555555 ldrbpl r5, [r5, #-1365] ; 0xfffffaab
00005054 <three>:
5054: 66666666 strbtvs r6, [r6], -r6, ror #12
Тогда для того, чтобы использовать эту таблицу переходов или посмотреть таблицу, вам нужно знать скомпилированный адрес против адреса во время выполнения, так что вы можете настроить время компиляции адрес в код.
Использование терминов, таких как физическое и страница, я думаю, что страница неверна, но это может быть виртуальное время vs link (я думаю, что скомпилированный - это неправильный термин, время связывания и время выполнения), все равно время выполнения и время ссылки зависит от причины поскольку разница - независимость позиции или виртуализация. Если вы работаете в операционной системе, время соединения и время выполнения должны быть одинаковыми, физическое не может быть обнаружено таким образом, так как процессор (adr), по крайней мере, как задокументировано, видит значение на ПК, а ПК не знает физического с виртуального, то есть от край сердечника в mmu. Поэтому я думаю, что оба термина физическое и страница неправильно используются здесь, но это только мое мнение.
Если вы удаляете -fPIC из своих параметров компилятора и не делаете его независимым от положения кодом, мне интересно, не будет ли это беспокоиться обо всем этом и просто используйте таблицу как есть.
Я не специалист по ARM, но 'adr' вычисляет адрес' 1' во время выполнения (т. Е. Всякий раз, когда этот код был перемещен), в то время как директива gas '.' - это смещение w.r.t. текущий раздел (или аналогичный, я тоже не специалист GAS). –