14.8变量类型
ARMC编译器支持基本的数据类型:char、short、int、longlong、float和double。表14.2说明了armcc对C语言所使用的数据类型的映射。
表14.2 C编译器数据类型映射
C数据类型
表示的意义
char
无符号8位字节数据
short
有符号16位半字数据
int
有符号32位字数据
long
有符号32位字数据
longlong
有符号64位双字数据
ARM指令集中,无论是数据处理指令还是数据加载/存储指令,处理的数据类型不同,指令的执行效率是不一样的。本章将详细讨论,如何在程序中为变量分配合理的数据类型,来提高代码的执行效率。
14.8.1局部变量
ARM属于RISC的体系结构,所有大多数的数据处理都是在32位的寄存器中进行的。基于这个原因,局部变量应尽可能使用32位数据类型int或long。
注意
一些情况下不得不使用char或short类型,例如要使用char或short类型的数据溢出指令时归零特性时,如模运算255+1=0,就要使用char类型。
为了说明局部变量类型的影响,先来看一个简单的例子。
charcharinc(chara)
{
returna+1;
}
编译出的结果如下。
charinc
ADDa1,a1,#1
ANDa1,a1,#&ff
MOVpc,lr
再把上面的程序段中变量a声明位int型,代码如下。
intwordinc(inta)
{
returna+1;
}
比较一下编译器输出结果。
wordinc
ADDa1,a1,#1
MOVpc,lr
分析上面的两段代码不难发现,当把变量声明为char型时,编译器增加了额外的ADD指令来保证其范围在0~255之间。
14.8.2有符号数和无符号数
上一节讨论了对于局部变量和函数参数,使用int型比使用char或short型要好。本节将对程序中的有符号整数(signedint)和无符号整数(unsignedint)的执行效率进行分析比较。
首先来看上一节的例子,如果将变量指定为有符号的半字类型(编译器默认short型为有符号类型),程序的源代码如下。
shortshortinc(shorta)
{
returna+1;
}
编译后的结果如下。
shortinc
ADDa1,a1,#1
MOVa1,a1,LSL#16
MOVa1,a1,ASR#16
MOVpc,lr
分析发现,该结果比使用int型的变量多增加了两条指令(LSL和ASR)。编译器先将变量左移16位,然后右移16位,以实现一个16位符号扩展。右移是符号位扩展移位,它复制了符号位来填充高16位。
通常情况下,如果程序中只有加法、减法和乘法,那么有符号和无符号数的执行效率相差不大。但是,如果有了除法,情况就不一样了。详细内容可参加除法运算优化一节。