11

据我了解,目标文件中的指令和数据都有地址。第一个数据项从地址 0 开始,第一条指令也从地址 0 开始。

重定位表包含有关在文件中的地址更改时需要更新的指令的信息,例如,如果文件与另一个文件链接在一起。在下面的示例中,行 A 将位于重定位表中。我认为 B 不会在重定位表中,因为标签“等于”的地址是相对于 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
4

1 回答 1

9

是的,你的假设是正确的。有多种类型的重定位,汇编器发出到指令中的内容取决于类型。通常它是要添加的偏移量。您可以使用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因此必须减去,并将其编码为ffff指令本身的 2 的补码。

la伪指令已由汇编器翻译成/luiaddiu(后者在 的延迟槽中jal)。对于将填充前 16 位的部分lui创建R_MIPS_HI16重定位。.data由于符号位于段TEXT中的地址处,因此偏移量的前 16 位为. 这意味着指令包含偏移量。类似地,对于低 16 位,除了该指令包含的偏移量为.4.data004

最后,jal printf正在使用另一种为指令所需的编码量身定制的重定位。偏移量为零,因为跳转直接到引用的符号。请注意,objdump 试图通过解码来提供帮助,但它不处理重定位,因此<main>它输出的当然是无稽之谈。

于 2013-05-25T14:02:49.110 回答