[原创]arm平台c语言函数传参及返回值约定浅析
测试用编译器:gcc
优化选项:-O2
a | 输入参数通过r0-r3传递,多余的放入堆栈中;返回值放入r0,不够的话放入 {r0,r1} |
例1 | int fun1(int a, int b, int c, int d) 输入:a = r0 b = r1 c = r2 d = r3 返回:r0 |
例2 | int* fun2(int a, double b, short c, char d) 输入:a = r0 r1用于对齐(double需要8字节对齐) b = {r2, r3} c 放在堆栈的sp[0]位置 d 放在堆栈的sp[4]位置,这里的sp是指进入函数时的sp 返回:r0 |
例3 | double fun3(double a, int b, short c, char d) 输入:a = {r0, r1} b = r2 c = r3 d 放在堆栈的sp[0]位置,这里的sp是指进入函数时的sp 返回:{r0,r1} |
b | 结构体作为参数传递时,当结构体内容{r0,r1,r2,r3}放不下时,多余的放入堆栈中 |
例1 | struct tagTest { int x; double y; }; int fun4(tagTest p) 输入:p.x = r0 r1 用于结构体对齐(8字节对齐) p.y = {r2,r3} |
例2 | struct tagTest { int x; double y; char z; }; int fun4(tagTest p) 输入:p.x = r0 r1 用于结构体对齐(8字节对齐) p.y = {r2,r3} z 放在堆栈的sp[0]位置,sp[4]同样会用于结构体对齐 |
c | 注意如果返回值是结构体,情况有些特殊 |
例 | struct tagTest fun5(int a, char b, float c) 输入:r0 = 一个strcut tagTest *变量,由调用者给出 r1 = a r2 = b r3 = c 返回:r0,和调用者给的一样 这其实和x86一致 |
