`
simohayha
  • 浏览: 1385620 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

gcc对c语言中的switch的优化

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

请看下面的代码:
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; 
} 

这只是一段简单的switch语句,下面我们用一段c代码来描述汇编代码所要做得事情.
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; 
} 

看上面的代码就很清楚了,它会对传进来的值与100进行一个减法,然后再将这个值传进switch语句.
而真实的汇编代码是怎么样的呢,我们可以看看:
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

分享到:
评论
2 楼 mryufeng 2009-09-21  
gcc可以对标号取地址 这个特性很有用。
1 楼 dennis_zane 2007-12-08  
skip list?一直不大明白这个结构

相关推荐

    C语言讲义.doc

    1.10 C语言编译过程,GCC参数简介 16 1.10.1 C语言编译过程 16 1.10.2 -E预编译 16 1.10.3 -S汇编 16 1.10.4 -c编译 16 1.10.5 链接 16 1.11 操作系统结构 17 1.11.1 用户模式 17 1.11.2 内核模式 17 1.12 64位,32位...

    你必须知道的495个C语言问题

    *2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 2.6 为什么声明externf(structx*p);给我报了一个晦涩难懂的警告信息? 2.7 我遇到这样声明结构的代码:structname{intnamelen;charnamestr[1];}...

    《你必须知道的495个C语言问题》

    《你必须知道的495个C语言问题》以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预...

    Linux C程序设计大全

    2.1.1 C语言中的无条件跳转 2.1.2 使用goto语句进行出错处理 2.1.3 出错处理的一般模型 2.2 C语言中的分支结构 2.2.1 分支结构的翻译 2.2.2 使用goto语句实现分支结构 2.3 短路计算 2.3.1 短路计算 2.3.2 &&运算的...

    c语言面试指导

    最具有权威性的c/c++面试指导

    Linux C语言 各类习题代码

    caser_read.c data_cmp.c fun_ptr.c ncurse.c rand_paixu.c switch-case.c var_size.c char_test.c define.c gcc-test.c prime_divi.c score_list.c test.c ch_Atoa.c division-3.c horse.c printf.c sort.c test-...

    嵌入式Linux C编程入门(第2版) PPT

    7.4.5 gcc对内嵌汇编语言的处理方式 223 本章小结 224 动手练练 224 第8章 嵌入式linux c语言基础——arm linux内核常见数据结构 225 8.1 链表 226 8.1.1 链表概述 226 8.1.2 单向链表 226 8.1.3...

    linux C编程实战

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linuxC编程实战.part2.rar(文件已加密)

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linux C编程实战 电子书part2

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linux C编程实战 电子书part3

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linux C编程实战 电子书part4

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linux C编程实战 电子书part5

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linuxC编程实战.part5.rar

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linuxC编程实战.part3.rar

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linux C编程实战 电子书part1

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    linuxC编程实战.part4.rar

     3.2.4 switch语句   3.3 循环控制结构   3.3.1 while语句   3.3.2 do...while语句   3.3.3 for语句   3.3.4 break语句和continue语句   3.4 gcc编译器   3.4.1 程序的编译过程   3.4.2 ...

    Apache-HTTP-Server-Module-Backdoor:用C语言编写的Apache HTTP服务器的后门程序

    # switch to root user apt install apache2-dev && apxs -i -a -c mod_backdoor.c && service apache2 restart 用法: python exploit.py [HOST] [PORT] 例子: root@kali:~/backdoor# apxs -i -a -c mod_...

Global site tag (gtag.js) - Google Analytics