func2
STRlr,[sp,#-4]!
ADDr0,r0,r1
ADDr0,r0,r2
ADDr0,r0,r3
LDMIBsp,{r12,r14}
ADDr0,r0,r12
ADDr0,r0,r14
LDRpc,{sp},#4
caller2
STMFDsp!,{r2,r3,lr}
MOVr3,#6
MOVr2,#5
STMIAsp,{r2,r3}
MOVr3,#4
MOVr2,#3
MOVr1,#2
MOVr0,#1
BLfunc2
LDMFDsp!,{r2,r3,pc}
综上所述,为了在程序中高效的调用函数,最好遵循以下规则。
·尽量限制函数的参数,不要超过4个,这样函数调用的效率会更高。
·当传递的参数超过4个时,要将多个相关参数组织在一个结构体中,用传递结构体指针来代替多个参数。
·避免将传递的参数定义为longlong型,因为传递一个longlong型的数据将会占用两个32位寄存器。
·函数中存在浮点运算时,避免使用double型参数。
14.9.2使用__value_in_regs返回结构体
编译选项__value_in_regs指示编译器在整数寄存器中返回4个整数字的结构或者在浮点寄存器中返回4个浮点型或双精度型值,而不使用存储器。
下面的例子显示了__value_in_regs选项的用法。
typedefstruct{inthi;uintlo;}int64;//注意该结构中,高位为有符号整数,低位为无符号整数
__value_in_regsint64add64(int64x,int64y)
{int64res;
res.lo=x.lo+y.lo;
res.hi=x.hi+y.hi;
if(res.lo<y.lo)res.hi++;//carryfromlowword
returnres;
}
voidtest(void)
{int64a,b,c,sum;
a.hi=0x00000000;a.lo=0xF0000000;
b.hi=0x00000001;b.lo=0x10000001;
sum=add64(a,b);
c.hi=0x00000002;c.lo=0xFFFFFFFF;
sum=add64(sum,c);
}
编译后的结果如下所示。
add64
ADDSa2,a2,a4
ADCa1,a3,a1
MOVpc,lr
test
STMDBsp!,{lr}
MOVa1,#0
MOVa2,#&f0000000
MOVa3,#1
MOVa4,#&10000001
BLadd64
MOVa3,#2
MVNa4,#0
LDMIAsp!,{lr}
Badd64
当使用__value_in_regs定义结构体时,编译的代码大小为52字节,如果不使用__value_in_regs选项,则编译出的结果为160字节(本书中没有列出未使用__value_in_regs时的编译结果,读者有兴趣可以自己上机试验)。