Я пытаюсь понять, как перемещения R_MIPS_HI16 и R_MIPS_LO16 работают в мипах.
Я написал немного кода c:
static char buf1[0x100];
static int a = 0;
static int b = 0;
char f(int i, int n)
{
a++;
b++;
return buf1[n];
}
Скомпилируйте с mips-linux-gnu-gcc-8 -o test.o -c -O2 -G 0 -g test.c
и запустите objdump: mips-linux-gnu-objdump -d -j .text test.o
Я получаю следующее:
00000030 <f>:
30: 3c070000 lui a3,0x0
34: 3c060000 lui a2,0x0
38: 3c020000 lui v0,0x0
3c: 8ce50004 lw a1,4(a3)
40: 8cc30000 lw v1,0(a2)
44: 24420008 addiu v0,v0,8
48: 00442021 addu a0,v0,a0
4c: 24a50001 addiu a1,a1,1
50: 24630001 addiu v1,v1,1
54: 80820000 lb v0,0(a0)
58: ace50004 sw a1,4(a3)
5c: 03e00008 jr ra
60: acc30000 sw v1,0(a2)
Теперь я запускаю mips-linux-gnu-readelf -r test.o
, чтобы получить таблицу перемещений:
Relocation section '.rel.text' at offset 0x79c contains 12 entries:
Offset Info Type Sym.Value Sym. Name
00000008 00000405 R_MIPS_HI16 00000000 .bss
00000018 00000406 R_MIPS_LO16 00000000 .bss
00000014 00000405 R_MIPS_HI16 00000000 .bss
0000001c 00000406 R_MIPS_LO16 00000000 .bss
00000030 00000405 R_MIPS_HI16 00000000 .bss
0000003c 00000406 R_MIPS_LO16 00000000 .bss
00000040 00000406 R_MIPS_LO16 00000000 .bss
00000038 00000405 R_MIPS_HI16 00000000 .bss
00000044 00000406 R_MIPS_LO16 00000000 .bss
00000058 00000406 R_MIPS_LO16 00000000 .bss
00000034 00000405 R_MIPS_HI16 00000000 .bss
00000060 00000406 R_MIPS_LO16 00000000 .bss
Теперь, согласно ABI , раздел 4-17, каждое перемещение R_MIPS_HI16 имеет соответствующий R_MIPS_LO16. В случае, если перед ним стоит R_MIPS_LO16 без R_MIPS_HI16, он будет ссылаться на предыдущий R_MIPS_HI16.
Если я понимаю это право, это означает, что перемещения в 38 и 44 являются парными. Это имеет смысл - в адресе 38 мы перемещаем верхнюю часть адреса в регистр (v0), а в 44 мы добавляем в тот же регистр, чтобы завершить загрузку адреса.
Что я не делаю Я понимаю, что перемещение в 58 также связано с тем же R_MIPS_HI16, но в этом адресе мы не обращаемся ни к какому регистру, который использовался в предыдущих командах, и они не кажутся связанными. На самом деле эта команда, похоже, относится к паре 30 и 3 c.
Что здесь происходит?