汇编控制类指令—— switch之跳转表

    switch语句可以根据一个整数索引值进行多重分支。处理具有多种可能结果的测试时,这种语句特别有用。它们不仅提高了代码的可读性,而且使用跳转表这个数据结构使用实现更加高效。跳转表是一个数组,表项i是一个代码段的地址,这个代码段实现当switch索引值等于i时程序应该执行的动作。程序代码用于索引值来执行一个跳转表内的数组引用,确定跳转指令的目标。和使用一组很长的
if-else相比,使用跳转表的优点是执行switch语句的时间与switch的case数量无关。GCC根据switch语句中case的数量和case中值的稀少程序来翻译开关语句。当case数据比较多(例如4个以上),并且值的范围跨度比较小时,就会使用跳转表。
  1. 编写switch.c程序如下:
int func(int x)
{
  int ret = -1;
  switch(x)
    {
    case 1: ret = 2; break;
    case 2: ret = 1; break;
    case 4:
    case 5: ret = 6; break;
    case 6: ret = 3; break;
    default: ret = 0; break;
    }
  return ret;
}
   2. 编译为汇编程序
unix> gcc -S switch.c
   3.查看汇编程序switch.s主要内容如下:
控制类汇编(3)—— switch语句分析 - strive_only - 奋斗,我要一直奋斗...等你...
    初步分析,x值存储在8(%ebp)位置,ret值存储在-4(%ebp)中。图中,.L7位置申请了一系列存储用于存储.L2~.L6的信息,每个元素为long型,占用4字节的空间(注意.L2处的代码是default的内容)。假如把.L7看成是一个数据,根据跳转表的原理,我们分析,若x处于1~4之间,只需执行.L7[x]处的程序即可,即跳转地址为.L7+4*x。
    按照上面思路,我们忽略程序过程调用的一些压栈操作和分配内存等操作从第15行看。第15、16行代码作用是比较x与5的大小,如果5<x,那么跳转到.L2(即switch.c中的default操作),否则把x的值加载到eax寄存器。行18把x的值扩大为原来的4倍,然后ADD .L8。计算得到要switch要跳转的地址,最后执行jmp *%eax(含义见 汇编控制类指令(2)—— 跳转指令).
   
    通过上面例子,我们知道C语言把跳转表声明为一个多元素的数组,第个元素都是一个指向代码的指针。跳转表对于重复情况处理就是简单地对重复项填入相同的标号(case 4、5),而对于缺失情况填入default的标号(switch内容为3时)。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值