iOS ARM64 汇编寻址
Position-independent code(PIC)
PIC(地址无关代码)为实现地址无关代码,在寻址过程中就要采用相对和动态的概念。
- 访问内部模块地址时,采用的是相对的概念,是基于PC的相对位置。
- 访问外部模块地址时,采用的是动态的概念,是基于数据段的间接访问。
内部模块寻址
bl指令
例子:
汇编:97 FF FF FF F1
指令bl:97
操作数:FF FF F1 = -0x0F
PC: 0x3F9C
寻址计算过程
目标地址 = PC - (0x0F << 2) = 0x3F9C - 0x3C = 0x3F60
ADR指令
例子:
ADR寻址结果写入寄存器x8
打印寄存器x8,目标地址:0x100003f9d
打印输出汇编:30 00 00 08 (0011 0000 0000 0000 0000 0000 0000 1000)
寻址计算过程
immlo = 01
immhi = 000 0000 0000 0000 0000
imm = immhi : immlo = 0x01
PC = 0x10003f9c
目标地址 = PC + imm = 0x10003f9c + 0x01 = 0x10003f9d
ADRP指令
例子:
ADRP寻址结果写入寄存器x8
打印寄存器x8,目标地址:0x10004000
打印输出汇编:B0 00 00 08 (1011 0000 0000 0000 0000 0000 0000 1000)
寻址计算过程
immlo = 01
immhi = 000 0000 0000 0000 0000
imm = (immhi : immlo) << 12 = (0x01) << 12 = 0x10000
PC(低12位清零)= 0x10003000
目标地址 = PC(低12位清零)+ imm = 0x10003000 + 0x10000 = 0x10004000
外部模块寻址
外部模块寻址,会先通过内部寻址找到 got 数据段 或 la_symbol_ptr 数据段的地址,然后再读取对应数据段存储的外部地址。外部地址会在运行时,写入数据段。 got 和 la_symbol_ptr 让外部模块的寻址过程有了动态特性。
例子:
通过ADRP指令寻址,目标地址x9 : 0x1001d4000
通过 image lookup 确认,寄存器x9存储的是数据段got的地址。
在读取 got 存储的外部地址后,再进行外部地址的访问。
结语
泛泛地记录下 iOS ARM64 的一些寻址过程。