http://infocenter.arm.com/help/index.jsp
ARM 寄存器
arm64有32个64bit长度的通用寄存器x0~x30,sp,可以只使用其中的32bit w0~w30
arm64有32个128bit SIMD寄存器v0~v31
arm32只有16个32bit的通用寄存器r0~r12, lr, pc, sp
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指针,指向下一条指令 |
通用寄存器名称
位数 | 通用 | 寄存器 | 栈指针 |
---|---|---|---|
32bit | wn | wZr | wsp |
64bit | xn | xZr | sp |
通用寄存器用法
1 | x0 - x7:用于传递子程序参数和结果,使用时不需要保存,多余参数采用堆栈传递,子程序返回结果写入到 x0 |
常用的汇编指令
汇编指令不区分大小写。即 mov 和 MOV 是一样的。
一条汇编指令是4字节大小。
1 | nop 什么也不做的指令,愣一下。没什么用途,但可以偏移指令地址。 |
其它
下面不作总结,简单说以下,方便查找。
.text
1 | .text 用于声明以下是代码段。 |
.align
.align 用于将指令对齐到内存地址,对齐位置为参数的 2 的幂次方。 以 .align 10 举例,在没有添加对齐时:
1 | func_1: |
得到的结果,两个指令构成了连续的地址,即指令之间相差
在 func_1 和 func_2 之间加入 .align 10:
1 | .align 10 |
得到如下结果,如果 .align 只是个普通的指令,那 func_2 的 ret 对应地址应当为递增4字节后的 0x0000000100008060,这里却变成了 0x000000010000840,0x000000010000840刚好是 2^10 的倍数。
.rept 和 .endr
.rept 和 .endr 是一组循环伪指令。
1 | func_1: |
生成了 5 个连续的 add 指令。
标签
如下代码:
1 | label: |
调用 label 就会执行 add x0, x0, x1 指令。
.globl
.globl 可以让一个标签对链接器可见,可以供其他链接对象模块使用。
如下代码:
1 | .globl label |
外部可以像 C 语言函数那样直接调用 label 标签方法。