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 //比較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各個分支語句的地址。