1、通用寄存器

64bit的寄存器有29个:x0 ~ x28,每个寄存器都是64bit(8个字节)。
64bit的寄存器也可以拆成32bit(4个字节)来用:w0 ~ w28,它们属于x0 ~ x28的低32bit。
image.png
可以通过LLDB的register指令来查看、修改寄存器的内容:
(lldb) register read x0

  1. x0 = 0x000000016d9bd080

(lldb) register read w0

  1. w0 = 0x6d9bd080

(lldb) register write x0 0x1
(lldb) register read x0

  1. x0 = 0x0000000000000001

(lldb) register read w0

  1. w0 = 0x00000001

可以看到修改了x0w0也随之更改了。
也可以查看所有寄存器:(lldb) register read

  1. General Purpose Registers:
  2. x0 = 0x0000000000000001
  3. x1 = 0x00000001f589e93a
  4. x2 = 0x0000000000000000
  5. x3 = 0x0000000283f96200
  6. x4 = 0x0000000000000001
  7. x5 = 0x0000000000000001
  8. x6 = 0x0000000000000000
  9. x7 = 0x0000000000000000
  10. x8 = 0x0000000104ae8660 dyld`_main_thread + 224
  11. x9 = 0x0000000000000001
  12. x10 = 0x0000000283f96200
  13. x11 = 0x00000003f1dfad6a
  14. x12 = 0x0000000000000000
  15. x13 = 0x0000000000000000
  16. x14 = 0x0000000023a00000
  17. x15 = 0xffffffffffffffff
  18. x16 = 0x00000001c4193d20 libobjc.A.dylib`objc_autoreleasePoolPop
  19. x17 = 0x00000001c4194098 libobjc.A.dylib`-[NSObject autorelease]
  20. x18 = 0x0000000000000000
  21. x19 = 0x0000000104b24060
  22. x20 = 0x0000000104982164 ARM64Study`main at main.m:11
  23. x21 = 0x0000000104ad4070 dyld`dyld4::sConfigBuffer
  24. x22 = 0x0000000000000000
  25. x23 = 0x0000000000000000
  26. x24 = 0x0000000000000000
  27. x25 = 0x0000000000000000
  28. x26 = 0x0000000000000000
  29. x27 = 0x0000000000000000
  30. x28 = 0x0000000000000000
  31. fp = 0x000000016b483750
  32. lr = 0xc43aee01049821c8 (0x00000001049821c8) ARM64Study`main + 100 at main.m:16:5
  33. sp = 0x000000016b483720
  34. pc = 0x00000001049821cc ARM64Study`main + 104 at main.m:17:30
  35. cpsr = 0x80000000

x0 ~ x7通常拿来存放函数的参数,更多的参数使用堆栈来传递。
x0通常拿来存放函数的返回值。

2、程序计数器

pc(Program Counter),存储着CPU当前正在执行的指令的地址。
(lldb) register read pc

  1. pc = 0x0000000104cd6288 ARM64Study`main + 32 at main.m:20:5

2、堆栈指针

sp(Stack Pointer)
fp(Frame Pointer),也就是x29

4、链接寄存器

lr(Link Register),也就是x30,存储着程序的返回地址。
(lldb) register read lr 或 (lldb) register read x30

  1. lr = 0x3e7c8a010294a1e0 (0x000000010294a1e0) ARM64Study`main + 100 at main.m:18:9

例如在main函数中调用test函数:

  1. ...
  2. 0x10206a1e8 <+108>: bl 0x102069fa0 ; test
  3. 0x10206a1ec <+112>: ldr x2, [sp, #0x8]
  4. ...

进入test函数后读取lr寄存器的值:

  1. lr = 0x000000010206a1ec ARM64Study`main + 112 at main.m:20:5

可以发现lr存储内容就是调用test函数下一条指令的地址值。当通过bl指令跳转函数前,会将下一条指令地址值存储到lr中,当函数调用ret指令时,CPU会执行lr中保存的指令,也就实现了继续执行的逻辑。

5、程序状态寄存器

5.1、cpsr

Current Program Status Register,当前程序状态寄存器,cpsr是64bit寄存器,但是只用到了32bit,每一位都有特定的用途:
image.png
各个标志为的含义如下:
image.png

5.2、spsr

Saved Program Status Register,异常状态下使用。

6、零寄存器

里面存储的值是0
wzr(32bit, Word Zero Register)
xzr(64bit)