我们来看下面的例子:
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结构的时候,为了使程序运行更快,应该避免使用区间差距
太大的数。
相关推荐
(7)Switch语句中根据发生频率来进行case排序 (8)将大的switch语句转为嵌套switch语句 (9)循环转置 (10)公用代码块 (11)提升循环的性能 (12)选择好的无限循环 6、提高CPU的并行性 (1)使用并行代码 (2...
3.1.1 算法反汇编代码分析 3.1.2 算法反汇编阅读技巧 3.2 发行版的反汇编 3.3 汇编反C语言练习 基础篇 内核编程 本书的第二部分,是编写Windows内核程序缡耩方法的基础。本部分包括第4-7章,如果读者对Windows内核...
3.1.1 算法反汇编代码分析 27 3.1.2 算法反汇编阅读技巧 28 3.2 发行版的反汇编 29 3.3 汇编反C语言练习 33 基础篇 内核编程 本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...
3.1.1 算法反汇编代码分析 27 3.1.2 算法反汇编阅读技巧 28 3.2 发行版的反汇编 29 3.3 汇编反C语言练习 33 基础篇 内核编程 本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...
3.1.1 算法反汇编代码分析 27 3.1.2 算法反汇编阅读技巧 28 3.2 发行版的反汇编 29 3.3 汇编反C语言练习 33 基础篇 内核编程 本书的第二部分,是编写Windows内核程序编程方法的基础。本部分包括第4~7章...
《你必须知道的495个C语言问题》以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预...
1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决了,是吗? 1.4 新的64位机上的64位类型...
接上电复位电路,以及手动复位电路,分析复位工作原理 接配置:EA(PIN31)。说明原因。 发光二极的控制:单片机 I/O 输出 将一发光二极管 LED 的正极(阳极)接 P1.1,LED 的负极(阴极)接地 GND。只要 P1.1 输出...
C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。 一、位运算符C语言提供了六种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 取反 左移 >> 右移 1. 按位与运算 按位与运算符"&"是双目...
C语言实现查表跳转程序.可以采用状态机如 switch(state) { case 1:state_fuc... 除了用switch或if判断,还有汇编那种goto 下面这种采用函数指针的办法.如下 void(*key_list[16])()={ key_zero, key_one, key_two,
6•C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。因此有人把它称为中级语言。 7•生成目标代码质量高,程序执行效率高。 8•与汇编语言相比,用C语言写的...
C语言实现查表跳转程序.可以采用状态机如 switch(state) { case 1:state_fuc... 除了用switch或if判断,还有汇编那种goto 下面这种采用函数指针的办法.如下 void(*key_list[16])()={ key_zero, key_one, key_two,
4. switch语句 5. 深入理解函数 1. return语句 2. 增量式开发 3. 递归 6. 循环语句 1. while语句 2. do/while语句 3. for语句 4. break和continue语句 5. 嵌套循环 6. goto语句和标号 7. 结构体 1. 复合类型与结构体...
在书写程序时,特别是对于While、for、do…while、if…elst、switch…case等语句或这些语句嵌套组合时,应采用“缩格”的书写形式, 2、标识符程序中使用的用户标识符除要遵循标识符的命名规则以外,一般不要用代数...
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)等主要内容。...