.

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 //比較edx和6
  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 7715ff24U...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 340000004...#...4...

Contents of section .comment:

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

001032203230 30383037 30342028 52656420220080704 (Red

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

通過檢視只讀資料段的內容,可以確定裡面儲存的就是switch各個分支語句的地址。