Таблица символов и таблица перемещений в объектном файле
Насколько я понимаю, инструкции и данные в объектном файле имеют адреса. Первый элемент данных начинается с адреса 0, а первая инструкция также начинается с адреса 0.
Таблица перемещения содержит информацию об инструкциях, которые необходимо обновить, если адреса в файле меняются, например, если файл связан вместе с другим. Строка A в приведенном ниже примере будет находиться в таблице перемещения. Я не думаю, что B будет в таблице перемещения, так как адрес метки "равно" относительно B. Являются ли эти правильные предположения?
Я знаю, что таблица символов показывает метки, которые есть в файле, а также метки, которые не были разрешены. Но какую еще информацию содержит таблица символов?
Кроме того, когда ассемблер переводит инструкции в двоичный файл, что помещается в эти инструкции, которые имеют неразрешенные ссылки? В этом примере.
.data
TEXT: .asciiz "Foo"
.text
.global main
main:
li t0, 1
beq t0, 1, equal #B
equal:
la a0, TEXT
jal printf #A
1 ответ
Да, ваши предположения верны. Существуют различные типы перемещений, которые ассемблер передает в инструкцию, зависит от типа. Обычно это смещение, которое будет добавлено. Ты можешь использовать objdump -dr
чтобы увидеть перемещения. Для лучшей иллюстрации я немного изменил ваш код:
.data
.int 0
TEXT: .asciiz "Foo"
.text
.global main
main:
li $t0, 1
beq $t0, 1, equal #B
bne $t0, 42, foo #C
equal:
la $a0, TEXT
jal printf #A
Вывод objdump:
00000000 <main>:
0: 24080001 li t0,1
4: 24010001 li at,1
8: 11010004 beq t0,at,1c <equal>
c: 00000000 nop
10: 2401002a li at,42
14: 1501ffff bne t0,at,14 <main+0x14>
14: R_MIPS_PC16 foo
18: 00000000 nop
0000001c <equal>:
1c: 3c040000 lui a0,0x0
1c: R_MIPS_HI16 .data
20: 0c000000 jal 0 <main>
20: R_MIPS_26 printf
24: 24840004 addiu a0,a0,4
24: R_MIPS_LO16 .data
Как вы сказали, переезд для beq
так как это относительный адрес в этом объектном файле.
bne
Я добавил (строка помечена C
) ссылается на внешний символ, поэтому, даже если адрес является относительным, необходима запись о перемещении. Это будет типа R_MIPS_PC16
произвести 16-битное смещение слова со знаком к символу foo
, Поскольку кодировка инструкции требует смещения от следующего слова, а не от текущего PC
что переезд использует, 1
должен быть вычтен, и это закодировано как дополнение 2 ffff
в самой инструкции.
la
псевдоинструкция была переведена ассемблером в lui
/addiu
пара (последняя в слоте задержки jal
). Для lui
R_MIPS_HI16
перемещение создается против .data
раздел, который заполнит верхние 16 бит. Поскольку символ TEXT
находится по адресу 4
в .data
раздел, верхние 16 битов смещения 0
, Это означает, что инструкция содержит 0
смещение. Аналогично, для младших 16 битов, за исключением того, что инструкция содержит смещение 4
,
Наконец, jal printf
использует еще один вид перемещения, адаптированный для кодирования, требуемого инструкцией. Смещение равно нулю, потому что переход непосредственно к указанному символу. Обратите внимание, что objdump пытается помочь, декодируя это, но не обрабатывает перемещение, поэтому <main>
это вывод, конечно, глупость.