扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
switch和ifelse的组合是不同的,不仅仅是代码看上去更清晰。
/////////////// C CODE /////////////////
// filename:asm05.c
/*show the switch*/
void fun_switch(int x)
{
int a;
switch(x)
{
case 10:
a=x;
break;
case 12:
a=x-2;
break;
case 16:
a=x-10;
case 18:
a--;
break;
case 19:
case 20:
a=10;
break;
default:
a=0;
}
}
/////////////// ASM CODE ////////////////
// command : gcc -S asm06.c
.file "asm06.c"
.text
.globl _fun_switch
.def _fun_switch; .scl 2; .type 32; .endef
_fun_switch:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
subl $10, %eax
movl %eax, -8(%ebp)
cmpl $10, -8(%ebp)
ja L9
movl -8(%ebp), %edx
movl L10(,%edx,4), %eax
jmp *%eax
.section .rdata,"dr"
.align 4
L10:
.long L3
.long L9
.long L4
.long L9
.long L9
.long L9
.long L5
.long L9
.long L6
.long L8
.long L8
.text
L3:
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
jmp L1
L4:
movl 8(%ebp), %eax
subl $2, %eax
movl %eax, -4(%ebp)
jmp L1
L5:
movl 8(%ebp), %eax
subl $10, %eax
movl %eax, -4(%ebp)
L6:
leal -4(%ebp), %eax
decl (%eax)
jmp L1
L8:
movl $10, -4(%ebp)
jmp L1
L9:
movl $0, -4(%ebp)
L1:
leave
ret
上面的汇编表示中有这样一段语句:
.section .rdata,"dr"
.align 4
L10:
.long L3 ;case 10
.long L9 ;default
.long L4 ;case 12
.long L9 ;default
.long L9 ;default
.long L9 ;default
.long L5 ;case 16
.long L9 ;default
.long L6 ;case 18
.long L8 ;case 19
.long L8 ;case 20
.text
这就是我们所谓的跳转表,它表示了一个相对的偏移,我们的最大值-最小值+default=11。
cmpl $10, -8(%ebp)
ja L9
movl -8(%ebp), %edx
movl L10(,%edx,4), %eax
这里我们拿x和10的差与偏移数(10)做比较,并按照跳转表中的表示,跳转到相应的位置去。所以它的执行效率
比较高。
当然,也不是总是这么理想化,我们对于switch的值如果比较紧凑可以很好的利用switch的优势,但是如果数
值跨度比较大,那么switch就不会使用跳转表了,比如我们把asm06.c中的最后一个条件case 20:改为case
2000: 那么,编译器会把它编译成为类似ifelse组合的形式:
/////////////// ASM CODE ////////////////
// command : gcc -S asm06.c
.file "asm06.c"
.text
.globl _fun_switch
.def _fun_switch; .scl 2; .type 32; .endef
_fun_switch:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -8(%ebp)
cmpl $16, -8(%ebp)
je L5
cmpl $16, -8(%ebp)
jg L10
cmpl $10, -8(%ebp)
je L3
cmpl $12, -8(%ebp)
je L4
jmp L9
L10:
cmpl $19, -8(%ebp)
je L8
cmpl $19, -8(%ebp)
jg L11
cmpl $18, -8(%ebp)
je L6
jmp L9
L11:
cmpl $2000, -8(%ebp)
je L8
jmp L9
L3:
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
jmp L1
L4:
movl 8(%ebp), %eax
subl $2, %eax
movl %eax, -4(%ebp)
jmp L1
L5:
movl 8(%ebp), %eax
subl $10, %eax
movl %eax, -4(%ebp)
L6:
leal -4(%ebp), %eax
decl (%eax)
jmp L1
L8:
movl $10, -4(%ebp)
jmp L1
L9:
movl $0, -4(%ebp)
L1:
leave
ret
////////////////////////////////
//2006-11-07 继续充电
////////////////////////////////
发现我也只能说到这里,再深入,还需要我继续修炼...希望能给初学C语言的朋友一些引导性的信息。没准儿
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者