Таблица символов и таблица перемещений в объектном файле

Насколько я понимаю, инструкции и данные в объектном файле имеют адреса. Первый элемент данных начинается с адреса 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> это вывод, конечно, глупость.

Другие вопросы по тегам