如何" __ ARM_common_switch8 PROC"在Keil uVision4中生产

时间:2016-12-13 11:51:13

标签: assembly arm

我写了一个包含switch声明的c程序:

int main(){
  char* i;
  int j;
  for(j=0;j<9;j++){
    switch(j){
        case 0: i[j]='a';break;
        case 1: i[j]='s';break;
        case 2: i[j]='s';break;
        case 3: i[j]='e';break;
        case 4: i[j]='m';break;
        case 5: i[j]='b';break;
        case 6: i[j]='l';break;
        default:i[j]='y';break;
      } 
  }
  return 0;
}

使用keil uVision4编译时,我在程序集文件中找到了一个名为__ARM_common_switch8的新函数:

__ARM_common_switch8 PROC
    PUSH     {r4,r5}
    MOV      r4,lr
    SUBS     r4,r4,#1
    LDRB     r5,[r4,#0]
    ADDS     r4,r4,#1
    CMP      r3,r5
    BCC      |L13.24|
|L13.14|
    LDRB     r3,[r4,r5]
    LSLS     r3,r3,#1
    ADDS     r3,r4,r3
    POP      {r4,r5}
    BX       r3
|L13.24|
    MOV      r5,r3
    B        |L13.14|
    ENDP

主PROC如下:

main PROC
    PUSH     {lr}
    MOVS     r1,#0
    B        |L1.74|
|L1.6|
    MOVS     r3,r1
    BL       __ARM_common_switch8
    DCB      0x07,0x05,0x08,0x0b
    DCB      0x0e,0x11,0x14,0x17
    DCB      0x1a,0x00
    MOVS     r0,#0x61
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x63
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x63
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x65
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x73
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x73
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x77
    STRB     r0,[r2,r1]
    B        |L1.70|
    MOVS     r0,#0x71
    STRB     r0,[r2,r1]
    NOP      
|L1.70|
    NOP      
    ADDS     r1,r1,#1
|L1.74|
    CMP      r1,#9
    BLT      |L1.6|
    MOVS     r0,#0
    POP      {pc}
    ENDP

__ARM_common_switch8 PROC是如何产生的?编译器可以生成新函数吗?顺便说一句,优化设置为O1 / O2 / O3级别,此功能将消失。

1 个答案:

答案 0 :(得分:0)

我在实验中遇到过这个问题。然后我发现当你使用7个以上的switch-cases时,compile会调用这个库函数-'ARM_COMMON_SWITCH8'来帮助计算程序切换到的地址。

据我所知,有两种方法可以解决这个问题。一种是将您的开关结构划分为几个较小的“条件结构”,例如“if和else”以及少于6种情况的开关结构。第二种方法是使用优化选项,例如'-O1,-O2,-O3,-Os'。