您的位置:首页 > 其它

【C】——C深入探讨——switch语句的default位置【转】

2013-03-05 21:22 253 查看
switch语句中的default位置可以随意放,一开始我想不通,就看了下简单反汇编的,发现原来只是靠default的标记,程序执行时先测试表达式是否满足某个case,若都不满足就跳到default去执行。本人目前还没进军反汇编界,请大牛不要取笑。

下面以两个简单的例子说明:

1)

main()
{
int a = 0;
int o = 0;
a = 4;
switch(a)
{
case 1:
o = 10;
printf("%d\n",o);
case 2:
o = 20;
printf("%d\n",o);
default:
o = 100;
printf("%d\n",o);
case 3:
o = 30;
printf("%d\n",o);
case 4:
o = 40;
printf("%d\n",o);
}

}

这样反汇编出来的是:

switch(a)

{

0040D79D mov eax,dword ptr [ebp-4] ;eax = a
0040D7A0 mov dword ptr [ebp-0Ch],eax ;[ebp-0Ch] = a
0040D7A3 mov ecx,dword ptr [ebp-0Ch] ;ecx = a
0040D7A6 sub ecx,1 ;ecx -= 1
0040D7A9 mov dword ptr [ebp-0Ch],ecx ;[ebp-0Ch] = ecx
0040D7AC cmp dword ptr [ebp-0Ch],3 ;比较[ebp-0ch]和3大小
0040D7B0 ja $L40+18h (0040d7ec) ;ecx大于3则跳到default
0040D7B2 mov edx,dword ptr [ebp-0Ch] ;
0040D7B5 jmp dword ptr [edx*4+40D845h];40D845h应该是指针存放的位置,这里就是跳到相应的case执行

case 1:

这里比较特殊,因为case都是相差1的,编译器做了优化,这样效率高一些。上面是检查a是否超出最大的case 4,超出就跳到default执行,否则就跳到相应的case。

2)

main()
{
int a = 0;
int o = 0;
a = 4;
switch(a)
{
case 1:
o = 10;
printf("%d\n",o);
case 20:
o = 20;
printf("%d\n",o);
default:
o = 100;
printf("%d\n",o);
case 300:
o = 30;
printf("%d\n",o);
case 40:
o = 40;
printf("%d\n",o);
}

}

反汇编代码:

switch(a)
{
0040D79D mov eax,dword ptr [ebp-4]
0040D7A0 mov dword ptr [ebp-0Ch],eax
0040D7A3 cmp dword ptr [ebp-0Ch],28h
0040D7A7 jg main+4Dh (0040d7bd)
0040D7A9 cmp dword ptr [ebp-0Ch],28h
0040D7AD je main+0B8h (0040d828)
0040D7AF cmp dword ptr [ebp-0Ch],1
0040D7B3 je main+58h (0040d7c8)
0040D7B5 cmp dword ptr [ebp-0Ch],14h
0040D7B9 je main+70h (0040d7e0)
0040D7BB jmp main+88h (0040d7f8)
0040D7BD cmp dword ptr [ebp-0Ch],12Ch
0040D7C4 je main+0A0h (0040d810)
0040D7C6 jmp main+88h (0040d7f8) ;这里是跳到default去
case 1:

这里是将各case改得复杂一点,没有规律了,然后程序就必须一个一个的验证case是否满足,都满足的话最后就直接jmp跳到default去执行。

总结:所以在程序中default的位置可以任意,因为编译到exe后,程序执行时先判断所有case,然后再判断是否跳到default的地址(即指针),然后往后执行,遇到break之类的就直接跳到后面去了。(而各case和default的内嵌语句又是顺序的)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: