我们来看下面的例子:
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结构的时候,为了使程序运行更快,应该避免使用区间差距
太大的数。
相关推荐
3. **控制结构**:包括条件语句(if...else)、循环(for、while)、开关语句(switch...case)。 4. **函数定义与调用**:如`void print(int num) { printf("%d", num); }`,定义了一个打印整数的函数,然后通过`...
- 控制结构:if-else语句用于条件判断,while和for循环实现重复执行,switch-case用于多分支选择。 - 函数:函数定义包括返回类型、函数名、参数列表和函数体。函数调用传递参数,实现代码复用。 - 指针:C语言的...
了解变量定义、数据类型、运算符、流程控制语句(如if-else、switch-case、for、while)以及函数等基本概念是使用C语言进行单片机编程的基础。 2. **单片机原理** 单片机是一种集成了CPU、内存、I/O接口等多种功能...
4. 控制流程:if-else条件语句、switch-case选择结构、for、while、do-while循环结构的使用。 5. 函数:函数的定义、调用、参数传递,以及函数间的调用关系。 6. 数组:一维、二维数组的声明、初始化和操作。 7. ...
6. **Switch语句优化**:根据case的发生频率进行排序可以减少搜索时间;将大的`switch`语句转换为嵌套的`switch`语句,可以使代码更清晰且高效。 7. **循环转置**:改变循环的顺序可以减少内存访问次数,提高缓存...
在编译器设计中,我们需要理解C语言的所有语法规则,包括变量声明、数据类型、运算符、流程控制语句(如if-else、switch-case、for、while)、函数定义与调用、指针操作等,这些都是编译器进行源代码解析的基础。...
2. **高效性**:C语言编译后的代码运行速度快,接近汇编语言。 3. **面向过程**:C语言是一种面向过程的语言,强调通过函数调用来实现模块化编程。 4. **可移植性**:C语言编写的程序可以轻易地在不同平台上重编译和...
4. switch语句在C语言中用于基于不同的case值执行不同的代码块,但它的参数必须是整数类型,不能是浮点数。 5. 常量的表示方法在C语言中有特定的规则,例如整数、实数、字符常量和字符串常量的表示。 6. 表达式的...
### C语言常见错误分析汇总 在C语言编程中,开发者可能会遇到各种各样的错误,这些错误不仅会影响程序的运行效率,还可能导致程序无法正常执行。本文将针对一系列常见的C语言错误进行详细的分析与总结,帮助开发者...
2. **控制结构**:包括条件语句(if-else)、循环(for、while)、switch-case等。这些结构在处理游戏逻辑时非常重要,例如判断玩家输入是否正确,或者控制游戏循环直到玩家完成单词。 3. **函数**:C语言中的函数...
压缩包中的“C语言源程序”很可能是示例代码或项目,通过分析和运行这些代码,可以更直观地学习C语言在单片机上的实际应用。这可能包括简单的LED灯控制、串口通信、定时器配置或ADC(模拟数字转换)读取等常见任务。...
3. **控制结构**:包括顺序结构、选择结构(if-else,switch-case)和循环结构(for,while,do-while)的应用,掌握条件分支和循环的嵌套。 4. **函数**:函数的定义、调用、参数传递,以及递归函数的理解和应用。...
然而,在某些特定情况下,比如代码分析、格式化或者去除敏感信息时,我们可能需要删除这些注释。本文将深入探讨如何利用C语言编写程序来实现这个功能,并结合编译原理中的有限自动机(Finite Automata)概念进行解释...
- 控制结构:包括条件语句(if...else、switch...case)和循环语句(for、while、do...while)用于实现程序的流程控制。 - 函数:函数是C语言中代码复用的关键,可以将一组相关操作封装在函数内部,通过函数调用来...
1. **基本语法**:包括变量定义、数据类型(如整型、浮点型、字符型等)、运算符(算术、关系、逻辑、赋值等)、流程控制(if-else、switch-case、循环语句for、while、do-while)。 2. **函数**:理解函数的作用、...
20. **Case outside of switch (switch外部的case)** - 在`switch`语句之外找到了`case`关键字。`case`只能出现在`switch`语句内部。 21. **Case statement missing (缺失case语句)** - 在`switch`结构中,某一个...
1. **基本语法**:C语言的基础包括变量(如整型、浮点型、字符型等)、数据类型、运算符(算术、比较、逻辑、位操作等)、控制结构(如if-else、switch-case、for、while、do-while循环)和函数定义。 2. **指针**...
11. C语言的switch语句通常用于基于不同的case值执行不同的代码块。选项C)switch((int)x%2)和D)switch((int)(x)%2)是合法的switch语句格式。 12. 在C语言中,变量在使用前需要正确定义。整型变量可以...
书中可能详细介绍了如何使用C语言编写汇编代码,以及如何控制硬件资源,例如中断服务程序的编写,以响应硬件事件。 内存管理在嵌入式系统中扮演着重要角色。由于嵌入式系统通常具有有限的内存资源,因此必须有效地...
2. **基本语法**:C语言的语法简洁明了,包括变量声明、常量定义、运算符、控制流(如if-else、switch-case、for、while等)、函数定义和调用等。理解这些基础元素是学习C语言的第一步。 3. **数据类型**:C语言...