谈一下switch语句中的jump table

gcc对c语言中的switch的优化 在这里:
http://simohayha.iteye.com/admin/show/146825

接着用上次的代码 switch.c
[code]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;
} [/code]
我们先键入下面的命令:
[code]cc -O2 -c switch.c[/code]
然后新建一个main.c的文件,内容为:
[code]
int main()
{
return switch_eg(102);
}[/code]
然后再键入

[code]cc -O2 -o switch switch.o main.c[/code]

这时会生成一个switch的二进制文件,我们将它反汇编:

[code]objdump -d switch[/code]
会生成很多代码,我这里只把重要的贴出来:
[code]08048350 <switch_eg>:
8048350: 55 push %ebp
8048351: 89 e5 mov %esp,%ebp
8048353: 8b 45 08 mov 0x8(%ebp),%eax
8048356: 8d 50 9c lea -0x64(%eax),%edx
8048359: 83 fa 06 cmp $0x6,%edx
804835c: 76 04 jbe 8048362 <switch_eg+0x12>
804835e: 5d pop %ebp
804835f: 31 c0 xor %eax,%eax
8048361: c3 ret
8048362: ff 24 95 80 84 04 08 jmp *0x8048480(,%edx,4)
8048369: 0f af c0 imul %eax,%eax
804836c: 5d pop %ebp
804836d: 8d 76 00 lea 0x0(%esi),%esi
8048370: c3 ret
8048371: 5d pop %ebp
8048372: b8 72 00 00 00 mov $0x72,%eax
8048377: c3 ret
8048378: 5d pop %ebp
8048379: b8 7b 00 00 00 mov $0x7b,%eax
804837e: 66 90 xchg %ax,%ax
8048380: c3 ret
8048381: 5d pop %ebp
8048382: b8 14 05 00 00 mov $0x514,%eax[/code]

注意看8048362这一行.这行就是进入跳转表的汇编代码,现在我们再进入test程序的调试:
[code]gdb test[/code]
然后键入:
[code]x/6w 0x8048480[/code]
这个命令是打印出从地址0x8048480开始的6个四字节的地址的内容.
会显示出下面的地址:
[code]0x8048480: 0x08048381 0x0804835e 0x08048378 0x08048371
0x8048490: 0x08048369 0x0804835e
[/code]
也就是说0x8048480里面存储的是0x08048381,0x08048384里面存储的是0x0804835e,然后是 0x08048378.....
这样的话,通过8048362那边的计算,就可以直接跳转到某个地址,从而把这个地址所存储的内容提取出来.


可以通过这些地址前去上面的代码里面找:
[code]0x08048381 : case 100
0x0804835e : case 101 (不存在所以跳转到default)
0x08048378 :case 102
0x08048371 :case 103
0x08048369 : 这边要注意,由于104是空语句,因此104 和106的case语句,编译器进行了合并,因此这边 即是 case 104也是case 106.
0x0804835e :case 105 (不存在所以跳转到default)[/code]

通过反汇编和调试信息,对switch的跳转表理解的更清晰了..
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值