我写了一个包含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级别,此功能将消失。
答案 0 :(得分:0)
我在实验中遇到过这个问题。然后我发现当你使用7个以上的switch-cases时,compile会调用这个库函数-'ARM_COMMON_SWITCH8'来帮助计算程序切换到的地址。
据我所知,有两种方法可以解决这个问题。一种是将您的开关结构划分为几个较小的“条件结构”,例如“if和else”以及少于6种情况的开关结构。第二种方法是使用优化选项,例如'-O1,-O2,-O3,-Os'。