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

  • 相关阅读:
    Shell 函数
    Linux shell脚本中shift的用法说明
    Python 命令行参数
    浅析 Jenkins 插件开发
    晒一晒Jenkins那些常用插件
    linux系统用vim编写python,实现自动补全
    C语言中printf的用法
    poj 1088 滑雪
    poj 1036 Gangsters
    hdu 1176 免费馅饼
  • 原文地址:https://www.cnblogs.com/ngnetboy/p/2945090.html
Copyright © 2011-2022 走看看