iOS汇编
iphone ARM64 汇编 GNU
模拟器 x86汇编 AT&T
寄存器
- 通用寄存器
- 64bit的 x0 ~ x28
- 32bit的 w0 ~ w28
- x0 - x7 一般为请求参数
- x0 一般为返回参数
- 程序计数器
- pc (Program Counter) 记录CPU当前执行的是哪一条指令,存储着当前CPU正在执行的地址,相当于 8086里的IP。
- 堆栈指针
- sp (Stack Pointer) 当前函数的栈顶
- fp (Frame Pointer) x29 当前函数的栈低
- 链接寄存器
- lr (Link Register) x30 调用函数的地址 A -> B A调用B, lr为A调用B函数时候的地址(B结束后要返回的地址)
- 程序状态寄存器
- cpsr (current program Status Register) 当前程序状态寄存器
- spsr (Saved Program Status Register) 异常状态下使用
汇编指令
- ret 函数返回
- mov (move)
- add sub
加 or 减
add x0, x1, x2 ; x0 = x1 + x2 add x0, x1, #256 ; x0 = x1 + 256 add x0, x1, x2 LSL#1 ; x0 = x1 + (x2 << 1) add x0, x1, x2, LSR#1 ; x0 = x1 + (x2 >> 1) sub x0, x1, x2 ; x0 = x1 - x2 sub x0, x1, #256 ; x0 = x1 - 256 sub x0, x1, x2 LSL#1 ; x0 = x1 - (x2 << 1) sub x0, x1, x2, LSR#1 ; x0 = x1 - (x2 >> 1)
- cmp 比较
- 两个寄存器相减
- 相减的结果影响CPSR寄存器
cmp x1, x0
- b 跳转
- bl 带返回的跳转指令 bl A
- bl的时候同时设置lr的地址为下一条指令的地址。
- A中执行ret的时候,把lr赋值给pc寄存器: PC=LR,这样程序下一条要执行的地址就是lr。这样就可以返回、
mycode:
mov x0, #01
mov x1, #02
ret
bl mycode ;跳转mycode 用bl mycode中的ret后回到mov x4, #0x1执行
mov x4, #0x1
mov x2, #0x1
mycode:
mov x0, #01
mov x1, #02
ret
b mycode ;跳转mycode 用b mycode中的ret没有效果,不会回到mov x4 #0x1
mov x4, #0x1
mov x2, #0x1
-
条件域
- eq (equal)相等就跳转。 CPSR Z位为1,就跳转
- ne (no equeal) 不等于
- gt (great than) 大于
- ge (great equal) 大于等于
- lt (less than) 小于
- le (less equal) 小于等于
-
内存操作
- load 从内存中装载数据
- ldr ldur
- ldp 成对装载 p:pairs
- store 往内存中存储数据
- str stur
- stp
- 零寄存器
- wzr(32bit) word zero register
- xzr(64bit)
- load 从内存中装载数据
ldr x0,[x1, #4] ;x0 = x1 + 4
ldr x0,[x1, #4]! ;x0 = x1 + 4 x1 = x1 + 4
ldr x0,[x1], #4 ;x0 = x1 x1 = x1 + 4
ldr x0 [r1, r2] ;x0 = r1 + r2
ldp x0, x1 [x2, #5] ;x0 = x2 + 5 从x2+5的地址取8个字节
;x1 = x2 + 5 + 8 从x2+5+8的地址取8个字节
;因为x0, x1大小是8个字节
str x0, [x1] ;把x0的数据写入到x1中 x1为地址。
str x0, [x1],#0x3 ;把x0的数据写入到x1中 x1为地址。
;x1 = x1 + 0x3
str x0, [x1, #0x3] ;把x0数据写入到 (x1地址+3)地址中
str x0, [x1, #0x3]! ;把x0数据写入到 (x1地址+3)地址中 x1 = x1 + 3
str x0, x1, [x2, #0x3] ;把x0数据写入到 (x1地址+3)地址中
;把x1数据写入到 (x2地址+3)+ 8 地址中 其中8是x0的长度,8个字节。
堆栈空间
- 叶子函数
- 内部不在调用其他函数
- 非叶子函数
叶子函数栈平衡不需要存LR和FP,因为不调用其他函数,不会更改。 非叶子函数栈平衡需要存LR和FP,因为调用内部函数会更改LR和FP
void A(){
B();
}
void B(){
c();
}
void C(){
}
LLDB 指令
register read
register read x0
regisster write x0 0x123