gcc对c语言中的switch的优化

在c语言中switch语句会被实现为一个跳转表,跳转表是一个数组,这个数组里面存的都是地址,也就是说只要你传递给它一个i,他就会返回给你,你所需要跳转的地址,这样做得好处就是执行语句的时间和条件的个数无关..不过在gcc里面他也只是条件数大于4个,才会生成这个跳转表.

请看下面的代码:
[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]
这只是一段简单的switch语句,下面我们用一段c代码来描述汇编代码所要做得事情.
[code]code *jt[7] = {
loc_A, loc_def, loc_B, loc_C,
loc_D, loc_def, loc_D
};

int switch_eg_impl(int x)
{
unsigned xi = x - 100;
int result = x;

if (xi > 6)
goto loc_def;

/* Next goto is not legal C */
goto jt[xi];

loc_A: /* Case 100 */
result *= 13;
goto done;

loc_B: /* Case 102 */
result += 10;
/* Fall through */

loc_C: /* Case 103 */
result += 11;
goto done;

loc_D: /* Cases 104, 106 */
result *= result;
goto done;

loc_def: /* Default case*/
result = 0;

done:
return result;
} [/code]
看上面的代码就很清楚了,它会对传进来的值与100进行一个减法,然后再将这个值传进switch语句.
而真实的汇编代码是怎么样的呢,我们可以看看:
[code]switch_eg:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax //这边得到传进来的参数
leal -100(%eax), %edx //这边将得到的参数和100做差
cmpl $6, %edx //这边和6比较,如果大于6说明下面的条件没有满足的所以默认进入default
jbe .L11
.L2:
popl %ebp
xorl %eax, %eax
ret
.p2align 4,,7
.L11:
jmp *.L7(,%edx,4) //这边也就是我们上面伪码所描述的那个jt[xi]
.section .rodata
.align 4
.align 4
.L7: //这边就是所构造的跳转表.
.long .L3
.long .L2
.long .L4
.long .L5
.long .L6
.long .L2
.long .L6
.text
.L6: // loc_D
imull %eax, %eax
popl %ebp
.p2align 4,,6
ret
.L5: //loc_c
popl %ebp
movl $114, %eax
.p2align 4,,6
ret
.L4: //loc_B
popl %ebp
movl $123, %eax
.p2align 4,,4
ret
.L3: //loc_A
popl %ebp
movl $1300, %eax
.p2align 4,,4
ret[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值