1.局部变量应该避免使用char 类型。
下面的程序用来计算一个包含64个字的数据包的校验和。
// 使用char 类型局部变量,说明为什么对局部变量应避免使用char 类型。
int checksum_v1(int *data)
{
char i;
int sum = 0;
for ( i = 0; i < 64; i ++ )
{
sum += data[i];
}
return sum;
}
初看一下,似乎声明i为char 类型是没有什么问题,甚至可能会觉得一个char类型的数据
比int类型的数据占用更小的寄存器空间或者更小的ARM堆栈空间。其实对ARM来说,这
两个设想都是错误的。所有ARM寄存器都是32位的,所有的堆栈入口也至少是32位的。
而且,为了正确执行i++,编译器必须解决i = 255时的情况,因为对于char 数据类型的
i 来说,255加1产生的结果是0.
编译后的结果:
checksum_v1
MOV r2, r0 ;r2 = data
MOV r0, #0 ;sum = 0
MOV r1, #0 ;i = 0
checksum_v1_loop
LDR r3, [r2, r1, LSL #2] ;r3 = data[i]
ADD r1, r1, #1 ;r1 = i + 1
AND r1, r1, #0xff ;i = (char) r1
CMP r1, #0x40 ;compare i, 64
ADD r0, r3, r0 ;sum += r3
BCC checksum_v1_loop ;if ( i < 64 ) loop
MOV pc, r14 ;return sum
现在把上面的程序段与把i声明为unsigned int 类型时比较一下:
checksum_v1
MOV r2, r0 ;r2 = data
MOV r0, #0 ;sum = 0
MOV r1, #0 ;i = 0
checksum_v1_loop
LDR r3, [r2, r1, LSL #2] ;r3 = data[i]
ADD r1, r1, #1 ;r1 = i + 1
CMP r1, #0x40 ;compare i, 64
ADD r0, r3, r0 ;sum += r3
BCC checksum_v1_loop ;if ( i < 64 ) loop
MOV pc, r14 ;return sum
第一种情况,在i 和64比较前,编译器增加了客外的AND指令来保证i 的范围为0 - 255,在第二种情况下,这条指令就可以省略了。