ARM 寄存器
ARM共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器.这些寄存器不能被同时访问,但在任何时候,通用寄存器R0~R14,程序计数器PC,一个或两个状态寄存器都是可访问的.
arm64有32个64bit长度的通用寄存器x0~x30,sp,可以只使用其中的32bit w0~w30。 arm32只有16个32bit的通用寄存器r0~r12, lr, pc, sp. arm64有32个128bit SIMD寄存器v0~v31,arm32有16个128bit SIMD寄存器Q0~Q15,又可细分为32个64bit SIMD寄存器D0~D31
函数调用:arm64前面8个参数都是通过寄存器来传递x0~x7, arm32前面4个参数通过寄存器来传递r0~r3,其他通过栈传递
iOS中ARMv7以及ARM64下的ABI:
- ARMv7中,对于通用寄存器,自己写的过程中需要保护R4、R5、R6、R7、R8、R9、R10、R11以及R14寄存器;NEON寄存器需要保存Q4、Q5、Q6、Q7寄存器。
- ARM64模式下,通用寄存器X18、X30不能被使用。而需要被自己写的过程所保护的是:X19、X20、X21、X22、X23、X24、X25、X26、X27、X28、X29寄存器;而SIMD寄存器需要保护的是V8、V9、V10、V11、V12、V13、V14、V15。
ARM汇编指令简介
常用寄存器
寄存器 | 位数 | 描述 |
---|---|---|
X0-X30 | 64bit | 64位通用寄存器 |
WO-W30 | 32bit | 32位通用寄存器 |
FP(x29) | 64bit | 栈底指针 |
LR (X30) | 64bit | 程序链接寄存器,保存跳转返回信息地址 |
SP | 64bit | 保存栈指针 |
PC | 64bit | 程序计数器,又称PC指针,指向下一条指令 |
通用寄存器名称
位数 | 通用 | 0寄存器 | 栈指针 |
---|---|---|---|
32bit | Wn | WZR | WSP |
64bit | Xn | XZR | SP |
通用寄存器用法
1 | X0-X7 用于函数调用时参数传递,X0一般用作返回值 |
常用的汇编指令
1 | MOV X1, X0 ;寄存器X0的值传给X1 |
反汇编
MacOS终端编译文件命令:将1.m 编译成 arm1
1 | clang -O0 -arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path` -o arm1 1.m |
赋值、加法和减法运算
C语言:
1 | #include <stdio.h> |
Hopper查看反汇编代码:
1 | _main: |
与、或和异或运算
C语言:
1 | #include <stdio.h> |
反汇编代码:
1 | _main: |
比较
CSPR条件码标记:
N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。
标志位 | 描述 |
---|---|
N | 当两个有符号整数运算时: N=1表示运算的结果为负数; N=0表示运算的结果为正数或零 |
Z | Z=1表示运算的结果为零 Z=0表示运算的结果非零 对于CMP指令,Z=1表示进行比较的两个数相等 |
C | 可以有4种方法设置C的值: 1. 在加法指令中(包括CMP指令),当结果产生了进位,则C=1,表示无符号运算发生上溢出;其他情况C=0 2. 在减法指令中(包括CMP指令),当运算中发生借位,则C=0,表示无符号运算数发生下溢出;其他情况下C=1 3. 对于包含移位操作的非加减运算指令,C中包含最后一次溢出的位的数值 4.对于其他非加减运算指令,C位的值通常不受影响 |
V | 对于加减运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出;通常其他指令不影响V位 |
常见的指令的条件码
条件码助记符 | 标志 | 描述 |
---|---|---|
NE | Z清零 | 不相等 |
EQ | Z置位 | 相等 |
LE | Z清零或(N不等于V) | 带符号数小于或等于 |
GE | N等于V | 带符号数大于或等于 |
LT | N不等于V | 带符号数小于 |
GT | Z清零且(N等于V) | 带符号数大于 |
HI | C置位Z清零 | 无符号数大于 |
LS | Z置位C清零 | 无符号数小于或等于 |
CC(LO) | C清零 | 无符号数小于 |
CS(HS) | C置位 | 无符号数大于或等于 |
C语言:
1 | #include <stdio.h> |
反汇编代码:
1 | _main: |
for循环
C语言:
1 | #include <stdio.h> |
反汇编代码:
1 | _main: |
while
C语言:
1 | #include <stdio.h> |
反汇编代码:
1 | _main: |
switch语句
C语言:
1 | #include <stdio.h> |
反汇编代码:
1 | _main: |
OC代码反汇编测试
创建一个APP项目,编译的时候选择真机
OC代码
1 | #import "AppDelegate.h" |
Hopper 反汇编代码:
1 | ================ B E G I N N I N G O F P R O C E D U R E ================ |
五. Xcode汇编分析
1 |
|
汇编代码
1 | demo1`main: |