1.ARM64汇编寄存器

184 阅读5分钟

要想学好arm64汇编,主要是学好三个方面

  • 寄存器
  • 指令
  • 堆栈

下面先学习寄存器

寄存器

通用寄存器

  • 64bit的:x0 ~ x28
  • 32bit的: w0 ~ w28(相当于从 64位的取出来 32位,然后将低32位拿出来用,x0 低 32位就是w0)
  • x0-x7通常拿来放到函数的参数,更多的参数使用堆栈来传递
  • x0 通常用来作为函数的返回值

查看寄存器可以通过

  • register read x0 读取某个寄存器的值
  • register write x0 0x0 将某个值写到某个寄存器里面
  • register read 不加参数,可以读出所有的寄存器
  • register read w0 读取x0寄存器的低32位
(lldb) register read x0
      x0 = 0x000000016f78cfb0
(lldb) register write x0 0x0
(lldb) register read x0
      x0 = 0x0000000000000000
(lldb) register read w0
      w0 = 0x00000000
(lldb) register read
General Purpose Registers:
        x0 = 0x000000016f78cfb0
        x1 = 0x0000000000000000
        x2 = 0x0000000283798ea0
        x3 = 0x00000002802b0000
        x4 = 0x000000021ac624ee  
        x5 = 0x0000000000007f14
        x6 = 0x000000021a5b8e6e  
        x7 = 0x000000021a709eee  
        x8 = 0x0a000002293a5aa1 (0x00000002293a5aa1) (void *)0x7000000002293a5a
        x9 = 0x0100000000000000
       x10 = 0x0a000002293a5aa1 (0x00000002293a5aa1) (void *)0x7000000002293a5a
       x11 = 0x0b000002293a5aa1 (0x00000002293a5aa1) (void *)0x7000000002293a5a
       x12 = 0x00000000000000a7
       x13 = 0x0000000000000000
       x14 = 0x0000000000000000
       x15 = 0xffffffffffffffff
       x16 = 0x00000001e906e170  libobjc.A.dylib`objc_release
       x17 = 0x000000022c12af40  (void *)0x00000001e906e170: objc_release
       x18 = 0x0000000000000000
       x19 = 0x000000015e80adb0
       x20 = 0x0000000283798e40
       x21 = 0x00000002802b0000
       x22 = 0x000000015e808840
       x23 = 0x000000021ac624ee  
       x24 = 0x0000000283798ea0
       x25 = 0x000000015e808840
       x26 = 0x00000002802b0000
       x27 = 0x0000000283798e40
       x28 = 0x00000002293ae800  UIKitCore`UIApp
        fp = 0x000000016f78cfd0
        lr = 0x0000000100674090  demo`-[ViewController touchesBegan:withEvent:] + 76 at ViewController.m:21
        sp = 0x000000016f78cf90
        pc = 0x0000000100674098  demo`-[ViewController touchesBegan:withEvent:] + 84 at ViewController.m:23:1
      cpsr = 0x80000000

零寄存器

wzr:这是一个64位的寄存器,他里面放的就是0,不能读,也不能写,只能用它给其他寄存器进行清零操作 xzr:这是一个32位的寄存器,他里面放的就是0,不能读,也不能写,只能用它给其他寄存器进行清零操作 为什么会存在这个零寄存器,是因为不论是对变量置为nil,还是置为null,都需要清零操作。

image.png

如果没有上面的wzr或者xzr 就需要下面的写法,为什么需要下面两步呢,因为str 指令 第一个操作数必须是寄存器,而不能是立即数,具体去看对应的指令

image.png

程序计数器 PC 寄存器

  • pc (Program Counter)
  • 记录CPU当前指令的是哪一条指令
  • 存储着当前CPU正在执行的指令的地址类似于8086汇编的ip寄存器

堆栈指针

  • sp (stack pointer) 栈顶指针
  • fp(Frame pointer) 栈底指针 也就是x29

链接寄存器LR

lr(Link Register),也就是x30,他的作用是 比方说我现在调用一个函数,函数执行完后,该返回到哪里,由lr寄存器存着返回的指令的地址。

注意点

arm 32 中的通用寄存器叫 R0,R1,而64位中叫 X0,X1