`

C语言汇编代码分析(switch case)

 
阅读更多

我们来看下面的例子:




 
 switch-case控制语句维护着一张跳转表(jump table),并不是用一系列的if-else来实现,在上例中就是标签L7标

记的地方。

 

跳转表方式大体思想是这样的:

 

用case语句中的最大值减去最小值求出一个区间,这里是106-100 = 6,即 0到6共有7个可能的case,此时编译器

为该switch-case控制分配长度为7的数组,然后编译器再去查询哪些case是出现了的,就在数组中对应位置填上该

case的地址(即L3,L4,L9,L6),如果没有对应的case就填写default对应的地址(即L2)。最后在执行的时候,只要

用switch的参数(即n)减去case中的最小值,就可以得到一个索引,用这个索引就可以直接跳转到对应的case语

句。这样比用if-else判断效率更高。

 

下面来具体分析下上面的汇编代码:

 

swithcase_asm:

pushl %ebp;函数管理用

movl %esp, %ebp;函数管理用

movl 8(%ebp), %eax;得到x

movl 12(%ebp), %edx;得到n

subl $100, %edx;用n-100存到%edx中

cmpl $6, %edx;比较%edx 与 6

ja .L2;如果%edx的值比6大则直接跳转到标签L2,即default

jmp *.L7(,%edx,4);如果小于等于6,在索引表中查找后跳转到对应的case

.section .rodata

.align 4

.align 4

.L7:                                            ;跳转表

.long .L3

.long .L2

.long .L4

.long .L9

.long .L6

.long .L2

.long .L6

.text

.L2:                                            ;default

movl $0, %eax

jmp .L8

.L3:                                            ;case 100

leal (%eax,%eax,2), %edx

leal (%eax,%edx,4), %eax

jmp .L8

.L4:                                           ;case 102

addl $10, %eax

.L9:                                           ;case 103

addl $11, %eax

jmp .L8

.L6:                                          ;case 104,106

imull %eax, %eax

.L8:

popl %ebp

ret

 

 

但是如果都采用跳转表的方式会有一个问题,那就内存消耗,如果case语句中最大值和最小值相差较大,

那么会消耗掉大量的内存,接下来我们来看编译器在这种情况下是如何处理的:

 


 
 

 

 我们将case 106改为case 1106,我们再看汇编代码,已经没有了跳转表的踪影了,没错,你猜对了,这种情况下编译器还是用了if-else控制方式。不过也用二分查找进行了优化(上面红色矩形框住的区域)。

 

那么通过上面的汇编分析,我们可以看出,在编写switch-case结构的时候,为了使程序运行更快,应该避免使用区间差距

太大的数。

 

 

  • 大小: 80.8 KB
  • 大小: 67.9 KB
分享到:
评论

相关推荐

    C语言代码优化 方案

    (7)Switch语句中根据发生频率来进行case排序 (8)将大的switch语句转为嵌套switch语句 (9)循环转置 (10)公用代码块 (11)提升循环的性能 (12)选择好的无限循环 6、提高CPU的并行性 (1)使用并行代码 (2...

    从汇编语言到Windows内核编程

    3.1.1 算法反汇编代码分析 3.1.2 算法反汇编阅读技巧 3.2 发行版的反汇编 3.3 汇编反C语言练习 基础篇 内核编程 本书的第二部分,是编写Windows内核程序缡耩方法的基础。本部分包括第4-7章,如果读者对Windows内核...

    天书夜谈:从汇编语言到Windows内核编程

     3.1.1 算法反汇编代码分析 27  3.1.2 算法反汇编阅读技巧 28  3.2 发行版的反汇编 29  3.3 汇编反C语言练习 33  基础篇 内核编程  本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...

    天书夜读:从汇编语言到Windows内核编程(完整版一)

     3.1.1 算法反汇编代码分析 27  3.1.2 算法反汇编阅读技巧 28  3.2 发行版的反汇编 29  3.3 汇编反C语言练习 33  基础篇 内核编程  本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...

    天书夜读:从汇编语言到Windows内核编程(完整版 二)

     3.1.1 算法反汇编代码分析 27  3.1.2 算法反汇编阅读技巧 28  3.2 发行版的反汇编 29  3.3 汇编反C语言练习 33  基础篇 内核编程  本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...

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

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

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

    1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决了,是吗? 1.4 新的64位机上的64位类型...

    51单片机C语言编程基础及实例

    接上电复位电路,以及手动复位电路,分析复位工作原理 接配置:EA(PIN31)。说明原因。 发光二极的控制:单片机 I/O 输出 将一发光二极管 LED 的正极(阳极)接 P1.1,LED 的负极(阴极)接地 GND。只要 P1.1 输出...

    c语言程序设计标准教程

    C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。 一、位运算符C语言提供了六种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 取反 左移 >> 右移 1. 按位与运算 按位与运算符"&"是双目...

    C语言实现函数查表跳转程序

    C语言实现查表跳转程序.可以采用状态机如 switch(state) { case 1:state_fuc... 除了用switch或if判断,还有汇编那种goto 下面这种采用函数指针的办法.如下 void(*key_list[16])()={ key_zero, key_one, key_two, 

    (谭浩强)c语言学习书

    6•C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。因此有人把它称为中级语言。 7•生成目标代码质量高,程序执行效率高。 8•与汇编语言相比,用C语言写的...

    EDA/PLD中的C语言实现函数查表跳转程序

    C语言实现查表跳转程序.可以采用状态机如 switch(state) { case 1:state_fuc... 除了用switch或if判断,还有汇编那种goto 下面这种采用函数指针的办法.如下 void(*key_list[16])()={ key_zero, key_one, key_two, 

    宋劲彬的嵌入式C语言一站式编程

    4. switch语句 5. 深入理解函数 1. return语句 2. 增量式开发 3. 递归 6. 循环语句 1. while语句 2. do/while语句 3. for语句 4. break和continue语句 5. 嵌套循环 6. goto语句和标号 7. 结构体 1. 复合类型与结构体...

    手把手教你如何优化C语言程序

    在书写程序时,特别是对于While、for、do…while、if…elst、switch…case等语句或这些语句嵌套组合时,应采用“缩格”的书写形式, 2、标识符程序中使用的用户标识符除要遵循标识符的命名规则以外,一般不要用代数...

    初学单片机经典例题.doc

    switch(ID){case 0:P1_0=~P1_0;break;case 1:P1_1=~P1_1;break;case 2:P1_2=~P1_2;break;case 3:P1_3=~P1_3;break;}}} 三. 99秒马表设计 1. 实验任务(1. 开始时,显示“00”,第1次按下SP1后就开始计时。(2. ...

    语言程序设计课后习题答案

    面向对象的软件工程是面向对象方法在软件工程领域的全面应用,它包括面向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。...

Global site tag (gtag.js) - Google Analytics