ARM 64系列寄存器,有哪些细节需要注意?

摘要:ARM 64中包含多种寄存器,下面介绍一些常见的寄存器。 1 通用寄存器 ARM 64包含31个64bit寄存器,记为X0~X30。 每一个通用寄存器,它的低32bit都可以被访问,记为W0~W30。 在这31个通用寄存器中,有2个寄存器比
ARM 64中包含多种寄存器,下面介绍一些常见的寄存器。 1 通用寄存器 ARM 64包含31个64bit寄存器,记为X0~X30。 每一个通用寄存器,它的低32bit都可以被访问,记为W0~W30。 在这31个通用寄存器中,有2个寄存器比较特殊。 X29寄存器被作为栈帧寄存器,也被称为FP(Frame Pointer Register)。 X30寄存器被作为函数返回地址寄存器,也被称为LR(Link Register)。 下面从一个例子来看X29寄存器与X30寄存器的作用。 // ARMAssemble`-[ViewController viewDidLoad]: 0x104e94000 <+0>: sub sp, sp, #0x30 0x104e94004 <+4>: stp x29, x30, [sp, #0x20] 0x104e94008 <+8>: add x29, sp, #0x20 ... 上面代码是一个VC viewDidLoad汇编方法的开头部分。 代码第1行将栈寄存器SP的值减少0x30,也就是开辟了0x30的栈空间。 代码第2行将寄存器X29与寄存器X30存入(sp + 0x20)指向的地址。 代码第3行将(SP + 0x20)这个地址值写入寄存器X29,形成新的栈帧FP。 从上图可以看到新FP存储在寄存器X29,而上一个栈帧FP的值被存入到地址(SP + 0x20)。这样,随着函数一层一层调用,栈帧也被串联起来。 对于寄存器X30,可以使用image lookup -a命令查看其存储的地址0x1c43df260代表的含义: (lldb) p/x $x30 (unsigned long) 0x00000001c43df260 (lldb) image lookup -a $x30 Address: UIKitCore[0x0000000189353260] (UIKitCore.__TEXT.__text + 3665488) Summary: UIKitCore`-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 84 从输出看到,这个地址位于函数-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled]中,正是这个函数调用了-[UIViewController viewDidLoad]。寄存器X30存储的地址0x1c43df260正是viewDidLoad函数返回后,要执行的指令地址: // UIKitCore`-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled]: ... 0x1c43df25c <+80>: bl 0x18a7b7e80 ; objc_msgSend$viewDidLoad // X30 的地址指向这行代码 0x1c43df260 <+84>: mov x0, x19 上面代码第1行调用函数-[UIViewController viewDidLoad]。 代码第2行就是函数-[UIViewController viewDidLoad]返回后要执行的指令,其地址正好是0x1c43df260。 2 SP SP是栈顶指针寄存器,类似Intel 64中的RSP寄存器。 3 PC PC寄存器存储当前要执行的指令地址,类似Intel 64中的RIP寄存器。 // ARMAssemble`-[ViewController viewDidLoad]: -> 0x104e94000 <+0>: sub sp, sp, #0x30 0x104e94004 <+4>: stp x29, x30, [sp, #0x20] ... 上面代码第1行,正要执行0x104e94000地址处指令,打印寄存器PC的值,也正好是0x104e94000: (lldb) p/x $PC (unsigned long) 0x0000000104e94000 4 SIMD&FP 寄存器 SIMD是单指令多数据的缩写(Signle Instruction,Multiple Data),FP代表浮点数(Float Point)。
阅读全文