ARM C 局部变量类型优化

ARM 78浏览

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,在第二种情况下,这条指令就可以省略了。