快速识别汇编中等价的C语言语句(if, while, for, switch)
来源:互联网 发布:七微南风知我意2微盘 编辑:程序博客网 时间:2024/05/17 23:51
注意:本文使用的汇编格式为GAS(Gnu ASembler GNU汇编器). 它同Intel文档中的格式以及微软编译器使用的格式差异很大,
具体请看文章AT&T汇编格式与Intel汇编格式的比较.
条件转移语句- if
============================
C语言中的if-else语句的通用形式如下
- if(test-expr)
- then-statement;
- else
- else-statement;
对于这种通用形式, 汇编实现通常会使用下面这种形式
- t= test-expr;
- if (t)
- goto true;
- else-statement
- goto done;
- true:
- then-statement
- done:
也就是汇编器为then-statement 和else-statement各自产生代码块, 并插入条件和无条件分支, 以保证正确代码块的执行.
下面我们来看C语言源代码, 汇编结构的C代码, 和汇编代码的比较.
- //----------Classic C code------------
- int absdiff(int x, int y)
- {
- if (x < y)
- return y - x;
- else
- return x - y;
- }
- //----------Classic C code------------
- //----------Equivalent Goto Version------------
- int gotodiff(int x, int y)
- {
- int rval;
- if (x < y)
- goto less;
- rval = x - y;
- goto done;
- less:
- rval = y - x;
- done:
- return rval;
- }
- //----------Equivalent Goto Version------------
- //----------Equivalent assembly Version------------
- movl 8(%ebp),%edx ;Get x
- movl 12(%ebp),%eax ;Get y
- cmpl %eax,%edx ;Compare x:y
- jl .L3 ;If <, goto less:
- subl %eax,%edx ;Compute y-x
- movl %edx,%eax ;Set as return value
- jmp .L5 ;Goto done:
- .L3: ;less:
- subl %edx,%eax ;Compute x-y as return value
- .L5: ;done:Begin completion code
- //----------Equivalent assembly Version------------
do-while循环
========================
do-while循环的通用形式是这样的:
- do
- {body-statement}
- while (test-expr);
循环的效果就是重复执行body-statement, 对test-expr求值, 如果不是0, 就继续循环. 注意, 循环体至少执行一次.
通常, do-while 的实现有下面的通用形式:
- loop:
- body-statement
- t= test-expr;
- if (t)
- goto loop;
下面是一个例子, 找找感觉吧.
- //----------Original C Version------------
- do{
- int t = val + nval;
- val = nval;
- nval = t;
- i++;
- } while (i < n);
- //----------Original C Version------------
- //----------Corresponding assembly code------------
- .L6: loop:
- leal (%edx,%ebx),%eax ;Compute t = val + nval
- movl %edx,%ebx ;copy nval to val
- movl %eax,%edx ;Copy t to nval
- incl %ecx ;Increment i
- cmpl %esi,%ecx ;Compare i:n
- jl .L6 If less, ;goto loop
- //---------Corresponding assembly code------------
while循环
========================
while语句循环的通用形式是这样的
- while(test-expr)
- body-statement
与do-while的不同之处在于对test-expr求值, 在第一次执行body-statement之前, 循环就可能终止了. 翻译成goto语句的形式就是
- loop:
- t= test-expr;
- if (!t)
- goto done;
- body-statement
- goto loop;
- done:
这种翻译需要在内循环(也就是执行次数最多的代码部分)中, 有两条goto语句. 大多数的编译器将这段代码转换成do-while循环, 把一个条件分支语句从循环体中拿到外面来.
- if (!test-expr)
- goto done;
- do
- body-statement
- while (test-expr);
- done:
然后, 再把这段代码换成带goto的语句的代码, 如下
- t= test-expr;
- if (!t)
- goto done;
- loop:
- body-statement
- t= test-expr;
- if (t)
- goto loop;
- done:
for循环
========================
for循环的通用形式是这样的:
- for (init-expr; test-expr; update-expr)
- body-statement
C语言的标准说明, 这样的一个循环的行为与下面这段使用while循环的代码的行为一样:
- init-expr;
- while (test-expr){
- body-statement
- update-expr;
- }
然后再用前面讲过的从while到do-while的转换. 首先给出do-while形式
- init-expr;
- if (!test-expr)
- goto done;
- do{
- body-statement
- update-expr;
- }while (test-expr);
- done:
再转换成goto代码
- init-expr;
- t= test-expr;
- if (!t)
- goto done;
- loop:
- body-statement
- update-expr;
- t= test-expr;
- if (t)
- goto loop;
- done:
相信现在, 你已经对汇编中的循环指令簇有点模式的感觉了吧? 呵呵. 我们再来看一个switch语句, 然后收工.
switch语句
======================
switch语句提供了一个整数索引值, 通过它来进行多重分支. 那么switch语句和一组很长的if-else语句相比, 有什么优势呢? 我先把答案说出来, 然后看看汇编, 就知道了.
优势就是: 执行开关语句的时间与开关情况的数量无关.
能做到这样的原因是跳转表. 跳转表是一个数组, 表项i是一个代码段的地址, 这个代码段实现的就是开关索引值等于i的时候应该采取的动作.
让我们来看一个例子, 这个例子包含一些很有意思的特征, 情况标号(case label)不连续, 比如101, 105; 一个情况有多个标号, 比如104, 106; 有些情况会落入其他情况(102), 因为该情况没有用break结尾.
- //----------Original C code------------
- 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;
- }
- //----------Original C code------------
说明问题的C的伪代码
- /* Next line is not legal 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;
- }
- //----------Corresponding assembly code------------
- //***********
- // Code that Set up the jump table access
- //***********
- leal -100(%edx),%eax ;Compute xi = x-100
- cmpl $6,%eax ;Compare xi:6
- ja .L9 ;if >, goto done
- jmp *.L10(,%eax,4) ;Goto jt[xi]
- //Case 100
- L4: ;loc A:
- leal (%edx,%edx,2),%eax ;Compute 3*x
- leal (%edx,%eax,4),%edx ;Compute x+4*3*x
- jmp .L3 ;Goto done
- //Case 102
- L5: ;loc B:
- addl $10,%edx ;result += 10, Fall through
- //Case 103
- L6: ;loc C:
- addl $11,%edx ;result += 11
- jmp .L3 ;Goto done
- //Cases 104, 106
- L8: ;loc D:
- imull %edx,%edx ;result *= result
- jmp .L3 ;Goto done
- //Default case
- L9: ;loc def:
- xorl %edx,%edx ;result = 0
- //Return result
- L3: ;done:
- movl %edx,%eax ;Set result as return value
- //----------Corresponding assembly code------------
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- C语言中流程控制语句(if,switch,for,while,do-while,continue,break,return)
- C++中四大语句总结(while、for、if、switch)
- C语言关键字--- if switch do while for
- c语言基础switch、if、while和for基本用法
- C语言笔试题精选1---求两个数之间较大的数,不使用if、while、switch、for、?:/以及任何比较语句
- C 语言的运算符表达式 if switch while
- swift控制语句,for,while,repeat-while,if,switch
- 控制流程语句if、switch、while、do-while、for
- 循环控制语句for while do-while if switch
- 3、C语言流程控制 if...else、switch、for、while、do while
- Matlab的if语句switch语句for循环while循环语句练习
- if,continue,break,while,do-while, switch,return,foreach,for等条件语句的使用
- matlab的if、switch、while语句
- 选择 | 循环 | 语句(if,if……else,switch,while,for)的理解和使用
- C语言的选择结构 (if 语句 和 switch 语句)
- sleep和wait有什么区别
- sss
- ThinkPHP 跨控制器页面跳转 官方文档 未讲清楚
- netty5笔记-线程模型3-EventLoop
- vm和主机互相ping不通
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- 前缀转中缀(利用栈)
- Python模块
- maven2中snapshot快照库和release发布库的应用
- Dropout原理介绍
- 标题和图片的兼容性
- flyway初始化脚本存在默认特殊字符的问题处理
- Python——debug
- 小米push