iOS ARM64 汇编寻址

580 阅读2分钟

iOS ARM64 汇编寻址

Position-independent code(PIC)

PIC(地址无关代码)为实现地址无关代码,在寻址过程中就要采用相对和动态的概念。

  • 访问内部模块地址时,采用的是相对的概念,是基于PC的相对位置。
  • 访问外部模块地址时,采用的是动态的概念,是基于数据段的间接访问。

内部模块寻址

bl指令

例子:

bl.png

汇编:97 FF FF FF F1

指令bl:97

操作数:FF FF F1 = -0x0F

PC: 0x3F9C

寻址计算过程

目标地址 = PC - (0x0F << 2) = 0x3F9C - 0x3C = 0x3F60

ADR指令

adr.png

例子:

adr-1.png

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-1.png

例子:

adrp.png

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 数据段的地址,然后再读取对应数据段存储的外部地址。外部地址会在运行时,写入数据段。 gotla_symbol_ptr 让外部模块的寻址过程有了动态特性。

例子:

wb.png

通过ADRP指令寻址,目标地址x9 : 0x1001d4000

通过 image lookup 确认,寄存器x9存储的是数据段got的地址。

在读取 got 存储的外部地址后,再进行外部地址的访问。

结语

泛泛地记录下 iOS ARM64 的一些寻址过程。