这篇主要介绍arm64程序调用规则,详细分析了程序调用过程当中,参数是如何传递的。Android、iOS、Linux等基本遵循这些规则,可是各个操做系统平台也有小部分本身特定的规则。下一篇,我将介绍iOS平台的特定规则。html
术语 | 意义 |
---|---|
A32 | 在ARMv7架构中,使用32位固定长度指令的ARM指令集。 |
A64 | AArch64可用时的指令集。 |
AAPCS64 | AArch64程序调用标准。(PCS:Procedure Call Standard) |
AArch32 | ARMv8中的32位通用寄存器,兼容ARMv7-A。 |
AArch64 | ARMv8中的64位通用寄存器 |
ABI(Application Binary Interface) | 汇编接口规范,跟执行环境相关,好比Linux ABI,说的是Linux环境下的汇编接口规范; |
ARM-based | 基于ARM |
Floating point | 根据上下文有这三种意思:(1)遵循IEEE 754 2008的浮点运算; (2)ARMv8浮点指令集; (3)一个被ARMv8浮点指令集和ARMv8 SIMD指令集共享的寄存器组。 |
Q-o-I | Quality of Implementation |
SIMD | Single Instruction Multiple Data 一条指令操做多个数据 |
T32 | T32使用可变16bit和32bit |
Routine, subroutine | Routine:调用者;subroutine:被调用者 |
Procedure | 没有返回值的函数 |
Function | 有返回值的函数 |
PIC, PID | Position-independent code, position-independent data. |
Program state | 指程序内存和寄存器的值 |
Caller- saved register | 调用者在调用函数以前,保存寄存器(通常入栈),函数返回后恢复寄存器(通常出栈) |
Callee-saved register | 被调用者(函数内部),在起始地方保存寄存器,在结束时,恢复寄存器 |
NGRN(The Next General-purpose Register Number ) | 能够理解为,记录r0-r7(见下文寄存器)使用个数,参数传递前设为0,每放一个参数进入寄存器(整型寄存器),值加1。当等于8时候,说明r0-r7寄存器使用完了,再有参数,只能放入内存了。 |
NSRN (The Next SIMD and Floating-point Register Number) | 同上,记录v0-v7使用个数 |
NSAA (The next stacked argument address) | 记录参数放入内存,参数传递前设为SP,因此内存中参数范围应该是 sp~NSAA。详细见下文参数传递 |
Type Class | Machine Type | Byte size |
Natural Alignment (bytes) |
---|---|---|---|
Integral | Unsigned byte | 1 | 1 |
Signed byte | 1 | 1 | |
Unsigned half- word |
2 | 2 | |
Signed half- word |
2 | 2 | |
Unsigned word | 4 | 4 | |
Signed word | 4 | 4 | |
Unsigned double-word |
8 | 8 | |
Signed double- word |
8 | 8 | |
Unsigned quad- word |
16 | 16 | |
Signed quad- word |
16 | 16 | |
Floating Point | Half precision | 2 | 2 |
Single precision | 4 | 4 | |
Double precision |
8 | 8 | |
Quad precision | 16 | 16 | |
Short vector | 64-bit vector | 8 | 8 |
128-bit vector | 16 | 16 | |
Pointer | Data pointer | 8 | 8 |
Code pointer | 8 | 8 |
arm64有两种寄存器:bash
寄存器 | 别名 | 意义 |
---|---|---|
SP | Stack Pointer:栈指针 | |
r30 | LR | Link Register:在调用函数时候,保存下一条要执行指令的地址。 |
r29 | FP | Frame Pointer:保存函数栈的基地址。 |
r19...r28 | Callee-saved registers(含义见上面术语解释) | |
r18 | 平台寄存器,有特定平台解释其用法。若是平台未把其作特殊用途,可当作临时寄存器使用。(iOS平台保留的寄存器,应用不可以使用) | |
r17 | IP1 | The second intra-procedure-call temporary register (can be used by call veneers and PLT code); at other times may be used as a temporary register. |
r16 | IP0 | The first intra-procedure-call scratch register (can be used by call veneers and PLT code); at other times may be used as a temporary register. |
r9...r15 | 临时寄存器 | |
r8 | 在一些状况下,返回值是经过r8返回的 | |
r0...r7 | r0-r7在函数调用过程当中传递参数和返回值 | |
NZCV | 状态寄存器:N(Negative)负数 Z(Zero) 零 C(Carry) 进位 V(Overflow) 溢出 |
arm64有31个通用整型寄存器,r0-r30。当使用64bits时候,命名x0-x30;使用32bits时,命名w0-w30。当寄存器在此程序调用标准中具备固定角色时,使用大写。架构
ARM64有32个寄存器v0-v31,用于处理SIMD和浮点运算。长度不一样称谓也不一样,b,h,s,d,q,分别表明byte(8位),half(16位),single(32位),double(64位),quad(128位)。v0-v7在函数调用过程当中传递参数和返回值;v8-v15 是Callee-saved registers(见术语解释),且是保存前64bits(更大的位数,调用者负责保存),v0-v7, v16-v31不须要保存或者调用者保存。app
一个进程的内存可分为5类:函数
可写静态数据能够细分为初始化,零初始化和未初始化数据。 除了栈以外,其它4类内存不须要占用连续的内存。 进程必须具备一些代码和栈,其它3类不是必须有。 堆是由进程管理的内存区域, 一般用于建立动态数据对象。post
地址空间包括一个或多个不相交的区域。 区域不能跨越零地址,可是能够从零开始。 标记寻址(tagged addressing)的使用是特定平台解释的。 当禁用标记寻址时,指针的全部64位都被传递到地址转换系统。 启用标记寻址时,为了进行地址转换,将忽略指针的前八位。注意:此tagged addressing,非iOS里的Tagged Pointer。spa
栈是连续的内存空间,可用于存储局部变量和参数传递(用于传递参数的寄存器不够用时候)。栈地址是从高到低,栈的地址保存在SP中。 栈使用限制:操作系统
A64指令集包含函数调用指令BL和BLR。 执行BL:PC(program counter)顺序的下一个值,也就是返回地址(函数调用完成返回要执行指令的地址),存放到LR中,将跳转地址传给PC。BLR跟BL相似,只不过PC的值是从寄存器中读取。.net
参数可经过r0-r七、v0-v7,栈来传递;若是参数个数很少,且参数可放进寄存器,那仅用寄存器传递参数。指针
可变参数可分为命名参数(已声明的)和匿名参数(可选的参数)。 当可变参数的函数,调用时候,没有可选参数时候(只有已声明的参数),调用过程和固定参数的函数同样的。
参数传递从概念上能够分为2阶段:
参数传递过程分为3个阶段:
阶段A – 初始化 (在开始处理参数以前,该阶段仅执行一次)
阶段B - 预填充和扩展参数 (把参数列表中的每个参数,去匹配下面规则,第一个被匹配到的规则,应用到该参数上。)
阶段C- 把参数放到寄存器或栈里 (参数列表中的每一个参数,将依次应用如下规则,直到参数放到寄存器或栈里,此参数处理完成,而后再从参数列表中取参数。注: 将参数分配给寄存器时,寄存器中未使用的位的值不肯定。 将参数分配给栈时,未填充字节的值不肯定。)
从上面规则,能够获得经验:
函数返回方式取决于返回结果的类型。
void func(T arg)
复制代码
arg值经过寄存器(组)传递,返回的结果也是经过相同的寄存器(组)返回。 2. 调用者申请内存(内存大小足够放入返回结果且是内存对齐的),将内存地址放入x8中传递给子函数,子函数运行时候,能够更新x8指向内存的内容,从而将结果返回。
假如文章有不对地方,欢迎你们留言指出;或者给我发邮件(wu_k_k@foxmail.com)。
--EOF-- 转载请保留连接,谢谢