32位汇编语言学习笔记(12)--分析switch语句的汇编代码



switch语句可以根据整数索引值进行多重分支选择,代码的可读性好,switch语句的汇编实现是通过跳转表来完成的,这样执行效率也很高。


int switch_eg(int x)

{

   int result = x;

 

   switch (x) {

 

   case 100:

         result*= 13;

         break;

 

   case 102:

         result+= 10;

         /*Fall through */

 

   case 103:

         result+= 11;

         break;

 

   case 104:

   case 106:

         result*= result;

         break;

 

   default:

         result= 0;      

    }

 

   return result;

}

 

gcc -c -O1 -m32 switch.c

objdump -d switch.o

 

switch.o:     file format elf32-i386

 

Disassembly of section .text:

 

00000000 <switch_eg>:

  0:   55                      push   %ebp

  1:   89 e5                   mov    %esp,%ebp

  3:   8b 45 08                mov    0x8(%ebp),%eax //eax = x = result

  6:   8d 50 9c                lea    0xffffff9c(%eax),%edx //edx = eax –0x64=eax-100

  9:   83 fa 06                cmp    $0x6,%edx //比较edx6

  c:   77 15                   ja     23 <switch_eg+0x23> //如果result 大于106

//跳转到0xe + 0x15= 0x23,default分支

   e:  ff 24 95 00 00 00 00    jmp    *0x0(,%edx,4) //跳转到.rodata的首地址处加4*edx偏移的地址处获取的地址就是要跳转的地址。

                                                                                      //edx大于等于0,小于等于6 。

 15:   b8 14 05 00 00          mov   $0x514,%eax //result = 0x514 =1300, case 100分支

 1a:   eb 1b                   jmp    37 <switch_eg+0x37> //跳转到0x1c+0x1b=0x37

 1c:   b8 70 00 00 00          mov   $0x70,%eax //eax = 0x70=112 case 102分支

 21:   eb 0c                   jmp    2f <switch_eg+0x2f> //跳转到0x0c+0x23=0x2f

 23:   b8 00 00 00 00          mov   $0x0,%eax //result=0,default分支

 28:   eb 0d                   jmp   37 <switch_eg+0x37>//跳转到0x0d+0x2a=0x37

 2a:   b8 67 00 00 00          mov   $0x67,%eax //result = 0x67=103 case 103分支

 2f:   83 c0 0b                add    $0xb,%eax //result += 11

 32:   eb 03                   jmp    37 <switch_eg+0x37> //跳转到0x03+0x34=0x37

 34:   0f af c0                imul   %eax,%eax //result *= result case 104,106分支

 37:   5d                      pop    %ebp

 38:   c3                      ret   


 jmp    *0x0(,%edx,4),0x0会在链接时填充为.rodata(只读数据段)的起始地址。 


objdump -s switch.o

 

switch.o:     file format elf32-i386

 

Contents of section .text:

 00005589e58b 45088d50 9c83fa06 7715ff24 U...E..P....w..$

 001095000000 00b81405 0000eb1b b8700000 .............p..ta

 002000eb0cb8 00000000 eb0db867 00000083 ...........g....

 0030c00beb03 0fafc05d c3                .......].       

Contents of section .rodata:

 000015000000 23000000 1c0000002a000000  ....#.......*...

 001034000000 23000000 34000000           4...#...4...   

Contents of section .comment:

 000000474343 3a202847 4e552920 342e312e .GCC: (GNU) 4.1.

 001032203230 30383037 30342028 52656420  220080704 (Red

 002048617420 342e312e 322d3434 2900      Hat4.1.2-44). 


通过查看只读数据段的内容,可以确定里面存储的就是switch各个分支语句的地址。

你可能感兴趣的:(32位汇编语言学习笔记(12)--分析switch语句的汇编代码)