刚接触 AArch64 汇编的人往往会对编译器生成的一类代码感到困惑。
考虑下面这样一个简单的 C 函数:
extern int foo;
int *bar(void) {
return &foo;
}
在开启 PIE(Position Independent Executable)后,不同架构的编译器通常会生成如下代码。
leaq foo(%rip), %rax
adrp x0, foo
add x0, x0, :lo12:foo
两种架构都采用了 PC-relative(PC 相对)寻址,即结合 PC 寄存器(x86-64 中的 %rip 或 AArch64 中的 pc)与预定义偏移量计算目标符号的最终地址。 但相比 x86-64 一条 LEA 指令即可完成地址计算,AArch64 却需要两条指令。这是为什么?
