zoukankan      html  css  js  c++  java
  • 【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的内嵌语句又是顺序的)

  • 相关阅读:
    NET 中反射的用法
    Prism 框架解读之一系列
    委托(Delegate)
    Python NameError:name ‘xrange’ is not defined
    Python import commands ImportError: No module named 'commands'
    Python import commands ImportError: No module named 'commands'
    Python3 TypeError: initial_value must be str or None, not bytes
    Python3 TypeError: initial_value must be str or None, not bytes
    Python import urllib2 ImportError: No module named 'urllib2'
    Python import urllib2 ImportError: No module named 'urllib2'
  • 原文地址:https://www.cnblogs.com/ngnetboy/p/2945090.html
Copyright © 2011-2022 走看看