はい、あなたの仮定は正しいです。再配置にはさまざまな種類があり、アセンブラが命令に出力するものは種類によって異なります。通常、追加するのはオフセットです。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
symbol への 16 ビットの符号付きワード オフセットを生成するタイプになりますfoo
。PC
命令のエンコードでは、再配置が使用する現在の値ではなく、次のワードからのオフセットが必要なため、1
減算する必要があり、それは 2 の補数としてffff
命令自体にエンコードされます。
la
疑似命令は、アセンブラによってlui
/ペアに変換されています(addiu
後者は の遅延スロットにありますjal
)。lui
再配置のために、上位 16 ビットを埋めるセクションR_MIPS_HI16
に対して作成されます。.data
シンボルTEXT
はセクション内のアドレス4
にあるため.data
、オフセットの上位 16 ビットは0
. これは、命令に0
オフセットが含まれていることを意味します。同様に、下位 16 ビットについても、命令に のオフセットが含まれている場合を除きます4
。
最後に、jal printf
命令で必要なエンコーディングに合わせて調整された、さらに別の種類の再配置を使用しています。ジャンプは参照シンボルに直接行われるため、オフセットはゼロです。objdump はそれをデコードすることで役立つことに注意してください。ただし、再配置を処理しないため、<main>
出力はもちろんナンセンスです。