基于ARM的高效C语言编程
add r3,[r2,r1,lsl #1];增加语句①
ldrh r3,[r3,#0]
add r1,r1,#1
and r1,r1,0xff;增加语句②
cmp r1,#0x0a
add r0,r3,r0
bcc add2_loop
mov r0,r0,lsl #16;增加语句③
mov r0,r0,asr #16;增加语句④
mov pc,r14
比较add1和add2两个函数的汇编代码,可以发现add2_loop循环比add1_loop循环增加了4条语句。
语句①:函数add2中变量sum为16位short类型,ARM指令中ldrh指令不支持移位地址偏移,因此增加add指令计算数组下标地址。
语句②:由于函数add2中循环变量i为8位的char类型,而ARM处理器的寄存器为32位,此语句用于处理循环变量累加过程中引起的溢出问题。即:当i累加到255时,再加1应该为0,而不是256。
语句③、④:函数add2中返回结果sum为short类型,在返回前需将32位寄存器的前16位用符号位填充,即转换为16位short类型。
2 函数局部变量的个数
为了加快程序的执行速度,函数编译时应尽可能将局部变量都分配在寄存器中。*部变量多于可用的寄存器时,编译器会将多余的变量压入堆栈(即存入存储器中),因此必须控制局部变量的个数。
ARM处理器采用RISC结构,带有丰富的内部寄存器。在编译器使用apcs开关选项,即支持ATPCS(ARMThumb Procedure Call STandard)标准时,理论上有14个寄存器(R0~R12,R14)可以用来存放局部变量。但是实际上有些寄存器有自身特殊的用途,例如R9在与读写位置无关(RWPI)的编译情况下作为静态基址寄存器使用,R12作为子程序内部调用的临时过渡寄存器使用。ATPCS规则中的寄存器名称及说明如表1所列。
表1 ATPCS规则中寄存器说明
因此,应尽量限制局部变量的数目:①对于函数的参数个数应控制在4个以内,只有R0~R3可用来保存参数,当参数多于4个时将被压入堆栈。如果由于实际应用的需要,参数多于4个,也可以采用结构体来组织参数,传递结构体指针来实现。②函数内部局部变量的个数应控制在12个以内(R0~R11),R12~R15都有特定用途。
3 函数内代码的编写
3.1 循环代码的编写
循环的控制条件设为递减到零的形式,可以减少指令条数。以求10个数的累加和为例进行分析。
代码1:
int sum=0;
for(int i=0;i10;i++)
sum=sum+i;
代码2:
int sum=0;
for(int i=10;i!=0;i--)
sum=sum+i;
评论