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

  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的内嵌语句又是顺序的)

原文地址:https://www.cnblogs.com/ngnetboy/p/2945090.html