C程序的机器级表示-5

/*********************************************/
 TEXT: C程序的机器级表示
 AUTHOR: arden chao
 DATE: 2006-10-17
 EMAIL:  arden1019@gmail.com
 VERSION:1.0.0
/*********************************************/


//2006-11-07 过程控制switch

switch和ifelse的组合是不同的,不仅仅是代码看上去更清晰。

///   C CODE   /
// filename:asm05.c

/*show the switch*/
void fun_switch(int x)
{
     int a;
     switch(x)
     {
         case 10:
              a=x;
              break;
         case 12:
              a=x-2;
              break;
         case 16:  
              a=x-10;
         case 18:
              a--;
              break;
         case 19:
         case 20:
              a=10;
         break;
         default:
              a=0;                                      
     }
}

///   ASM CODE  
// command : gcc -S asm06.c

 .file "asm06.c"
 .text
.globl _fun_switch
 .def _fun_switch; .scl 2; .type 32; .endef
_fun_switch:
 pushl %ebp
 movl %esp, %ebp
 subl $8, %esp
 movl 8(%ebp), %eax
 subl $10, %eax
 movl %eax, -8(%ebp)
 cmpl $10, -8(%ebp)
 ja L9
 movl -8(%ebp), %edx
 movl L10(,%edx,4), %eax
 jmp *%eax
 .section .rdata,"dr"
 .align 4
L10:
 .long L3
 .long L9
 .long L4
 .long L9
 .long L9
 .long L9
 .long L5
 .long L9
 .long L6
 .long L8
 .long L8
 .text
L3:
 movl 8(%ebp), %eax
 movl %eax, -4(%ebp)
 jmp L1
L4:
 movl 8(%ebp), %eax
 subl $2, %eax
 movl %eax, -4(%ebp)
 jmp L1
L5:
 movl 8(%ebp), %eax
 subl $10, %eax
 movl %eax, -4(%ebp)
L6:
 leal -4(%ebp), %eax
 decl (%eax)
 jmp L1
L8:
 movl $10, -4(%ebp)
 jmp L1
L9:
 movl $0, -4(%ebp)
L1:
 leave
 ret

上面的汇编表示中有这样一段语句:
 .section .rdata,"dr"
 .align 4
L10:
 .long L3 ;case 10
 .long L9 ;default
 .long L4 ;case 12
 .long L9 ;default
 .long L9 ;default
 .long L9 ;default
 .long L5 ;case 16
 .long L9 ;default
 .long L6 ;case 18
 .long L8 ;case 19
 .long L8 ;case 20
 .text
这就是我们所谓的跳转表,它表示了一个相对的偏移,我们的最大值-最小值+default=11。

 cmpl $10, -8(%ebp)
 ja L9
 movl -8(%ebp), %edx
 movl L10(,%edx,4), %eax

这里我们拿x和10的差与偏移数(10)做比较,并按照跳转表中的表示,跳转到相应的位置去。所以它的执行效率

比较高。
当然,也不是总是这么理想化,我们对于switch的值如果比较紧凑可以很好的利用switch的优势,但是如果数

值跨度比较大,那么switch就不会使用跳转表了,比如我们把asm06.c中的最后一个条件case 20:改为case

2000: 那么,编译器会把它编译成为类似ifelse组合的形式:

///   ASM CODE  
// command : gcc -S asm06.c

 .file "asm06.c"
 .text
.globl _fun_switch
 .def _fun_switch; .scl 2; .type 32; .endef
_fun_switch:
 pushl %ebp
 movl %esp, %ebp
 subl $8, %esp
 movl 8(%ebp), %eax
 movl %eax, -8(%ebp)
 cmpl $16, -8(%ebp)
 je L5
 cmpl $16, -8(%ebp)
 jg L10
 cmpl $10, -8(%ebp)
 je L3
 cmpl $12, -8(%ebp)
 je L4
 jmp L9
L10:
 cmpl $19, -8(%ebp)
 je L8
 cmpl $19, -8(%ebp)
 jg L11
 cmpl $18, -8(%ebp)
 je L6
 jmp L9
L11:
 cmpl $2000, -8(%ebp)
 je L8
 jmp L9
L3:
 movl 8(%ebp), %eax
 movl %eax, -4(%ebp)
 jmp L1
L4:
 movl 8(%ebp), %eax
 subl $2, %eax
 movl %eax, -4(%ebp)
 jmp L1
L5:
 movl 8(%ebp), %eax
 subl $10, %eax
 movl %eax, -4(%ebp)
L6:
 leal -4(%ebp), %eax
 decl (%eax)
 jmp L1
L8:
 movl $10, -4(%ebp)
 jmp L1
L9:
 movl $0, -4(%ebp)
L1:
 leave
 ret


//2006-11-07 继续充电

发现我也只能说到这里,再深入,还需要我继续修炼...希望能给初学C语言的朋友一些引导性的信息。没准儿

等我修炼好了还会继续写呵呵。我的目标是那天某一大学能让我当他们的C语言老师,我在为此做着努力。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值