要想学好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,都需要清零操作。
如果没有上面的wzr或者xzr 就需要下面的写法,为什么需要下面两步呢,因为str 指令 第一个操作数必须是寄存器,而不能是立即数,具体去看对应的指令
程序计数器 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