switch语句的反汇编

  switch语句反汇编的几种形式 

  0x00

  当case后面的常量较少时:

 

switch (x)
    {
    case 1:
        printf("1");
        break;
    case 2:
        printf("2");
        break;
    case 3:
        printf("3");
        break;
    default:
        printf("error");
        break;
    }

  下面为它的汇编代码

  

 

 

 

   可见,当常量减少时,switch的判断类似于if else语句,但不同的是,switch的判断都是集中在一起,而功能放在另一块地方,所以switch要与break一起使用

  0x01

  当case后面的常量较多且较连续时

  

switch (x)
    {
    case 1:
        printf("1");
        break;
    case 2:
        printf("2");
        break;
    case 3:
        printf("3");
        break;
    case 4:
        printf("4");
        break;
    case 5:
        printf("5");
        break;
    case 6:
        printf("6");
        break;
    case 7:
        printf("7");
        break;
    case 8:
        printf("8");
        break;
    default:
        printf("error");
        break;
    }

  以下为它的汇编代码

  

 

   这时候就有了switch的大表,编译器将整形变量x减去case后最小的常量1,并存储在edx中,通过一个确定的地址加上偏移确定应该转移的地址

       

  如果去掉case 3和case 4,此时的大表发生了变化

   

  3和4所对应的内存中存储了0x00401a70,这正是default所在的地址,也就是说当常量间隔的不多时,编译器仍然会使用大表。

 

  0x11

  当case后的常量连续但间隔过多的时候,此时出现了小表来配合大表使用,目的是为了节省空间

          小表                                                               大表

                        

 

 

  小表将出现的常量1~11对应的偏移都存储在内存中,每个占据一个字节,而大表中省去了因为间隔而浪费的多个双字的内存单元,因此实现了节省空间

 

 

  例如,常量1在小表中对应的0x00,存储在eax中,因此在大表中对应的是0x008b1a1d;常量2在小表中对应的是0x05,存储在eax中,因此在大表中对应的是0x008b1a68,即default所在的地址。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

  

 

posted @ 2021-03-05 15:52  Yanmo  阅读(205)  评论(0)    收藏  举报