Chinaunix首页 | 论坛 | 博客
  • 博客访问: 117134
  • 博文数量: 24
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 261
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-07 17:49
文章分类

全部博文(24)

文章存档

2009年(24)

我的朋友

分类: C/C++

2009-08-07 18:00:16

我土星了,GCC比CSAPP里说的更聪明了,对switch程序编译不用跳转表了。

对比VC2008和gcc给出的汇编代码,能发现VC倒还在用跳转表,gcc的汇编代码由于不用跳转表,更小更紧凑,却也更难读了。


C程序


int switchfunc(int x)
{
int result = 100;
switch (x)
    {
    case 100:
      result += 0;
      break;
      
    case 101:
      result += 1;
      break;
      
    case 102:
      result += 2;
      
    case 103:
      result += 3;
      break;
      
    default: // we do nothing

      ;
    }
return result;
}



VC 2008 编译版本

ASM不是很会,不过看得出来是按照跳转表编译的。

PUBLIC _switchfunc
; Function compile flags: /Ogtpy
; File e:\cpp\switch.c
_TEXT SEGMENT
_x$ = 8 ; size = 4
_switchfunc PROC

; 3 : int result = 100;
; 4 : switch (x)

mov ecx, DWORD PTR _x$[esp-4]
add ecx, -100 ; ffffff9cH
mov eax, 100 ; 00000064H
cmp ecx, 3
ja SHORT $LN1@switchfunc
jmp DWORD PTR $LN10@switchfunc[ecx*4]
$LN4@switchfunc:

; 5 : {
; 6 : case 100:
; 7 : result += 0;
; 8 : break;
; 9 :
; 10 : case 101:
; 11 : result += 1;

mov eax, 101 ; 00000065H

; 19 : break;
; 20 :
; 21 : default: // we do nothing
; 22 : ;
; 23 : }
; 24 : return result;
; 25 : }

ret 0
$LN3@switchfunc:

; 12 : break;
; 13 :
; 14 : case 102:
; 15 : result += 2;

mov eax, 102 ; 00000066H
$LN2@switchfunc:

; 16 :
; 17 : case 103:
; 18 : result += 3;

add eax, 3
$LN1@switchfunc:

; 19 : break;
; 20 :
; 21 : default: // we do nothing
; 22 : ;
; 23 : }
; 24 : return result;
; 25 : }

ret 0
npad 1
$LN10@switchfunc:
DD $LN1@switchfunc
DD $LN4@switchfunc
DD $LN3@switchfunc
DD $LN2@switchfunc
_switchfunc ENDP
_TEXT ENDS
END


Linux GCC编译版本

gcc做了不少很聪明的优化。就像看到102不break跳到103,gcc直接把105赋值给%eax。

而且怎么没看到上来就赋值100给%eax呢?


switchfunc:
    pushl %ebp
    movl $105, %eax
    movl %esp, %ebp
    movl 8(%ebp), %edx
    cmpl $102, %edx
    je .L6
    cmpl $103, %edx
    movb $103, %al
    je .L6
    xorl %eax, %eax
    cmpl $101, %edx
    sete %al
    addl $100, %eax // 答案就在这里
.L6:
    popl %ebp
    ret

阅读(1782) | 评论(0) | 转发(0) |
0

上一篇:show_bytes的C++版本

下一篇:程序的对齐

给主人留下些什么吧!~~