汇编语言 跳转指令与C语言的条件分支

跳转指令

跳转指令也是一个组的指令,称为j组。其中jmp为无条件跳转,其余为条件跳转

上图为j组指令,可结合条件码访问指令加深理解

在机器指令水平上理解如何对跳转指令编码

  • 如上图,通过反汇编软件得到机器指令与汇编语言,其中左边为机器指令编码,右边为对应汇编语言含义,最左边为每条机器指令地址
  • jmp指令的对应机器指令有两个字节:eb表示这是jmp指令,03描述跳转信息。值得注意的是,跳转指令进行编码时,采用相对位置编码,如03描述的就是偏移量
  • 结合实例进行理解:在未执行jmp指令时,rip寄存器存储的地址为4004d5(rip寄存器存放即将加载的指令地址);执行jmp指令后,rip寄存器的值改为新的目标位置地址,目标位置=原先位置+偏移量,在此例子中为4004d5+03=4004d8。jg指令同理
  • 存放相对位置意义:可获得更高灵活度,若存放绝对地址,分配地址可能改变;而相对位置一定不変

使用汇编语言的跳转指令实现C语言的条件分支

如上图,左边的程序可以通过上边的指令翻译成汇编指令

对上边指令的理解:

  • control.c为输入的文件
  • -s表示把c语言程序翻译为汇编指令
  • -og是一种程序优化形式。这种形式优化程度较低,但是是在不改变程序原有结构的前提下进行优化,故而能更加清楚的看到程序语言和汇编语言间的关系。在实际应用中,-o1、-o2优化程度更高,能更大程度提高程序性能,尤其-o2已经成为当前的主流标准。但是这两种形式可能改变原有高级语言的语句结构,难以建立高级语言和汇编指令间的映射关系,故在学习中不采用
  • -fno-if-conversion告诉编译器,在编译时,不要把分支语句用条件传输指令去执行,而用跳转指令执行。在早期X86处理器中,分支语句只又跳转指令表示,但后来又加入了条件传输指令,现在许多处理器用条件传输指令表示分支语句

使用条件数据传输指令实现条件分支

  • 条件数据传输指令,先计算条件结果,然后根据条件结果的具体状态,来决定是否把原操作数的值赋值到目标操作数
  • 和传统mov指令相似,只不过相当于在mov指令前需要判断条件,若条件不符合要求,啥都不做;符合要求,进行赋值
  • 既然已经有了跳转指令,为何要引入条件数据传输指令:跳转指令存在性能问题。处理器体系结构中有流水线技术,可实现对于指令执行的加速。但流水线须执行对指令的预先读取,预读的通常策略是顺序取址。若遇到跳转指令,无法事先判断是否进行跳转,导致跳转指令对流水线指令的预取有破坏意义。尽管流水线做了大量工作来避免破坏性(如分支预测),但无论如何弥补,都可能导致程序性能下降。而条件数据传输指令会预先将条件计算出来,然后判断是否进行赋值(即赋值指令是否执行),从而避免了对流水线的破坏。尽管增加了计算量,但对流水线性能优化要高于计算性能的代价

结合实例

指令就是跳转指令去掉-fno-if-conversion

条件数据传输指令过程:

把一种情况的结果(x-y)先计算出来,放到rax寄存器;另一种同样计算出来,放到rdx寄存器;然后比较x与y大小

比较大小时用到cmov指令组,与set指令组类似。如cmovle是在小于等于的情况下,将rdx赋值给rax;大于则保持原状。

条件数据传输指令可对性能进行很好的优化,但不是所有条件数据分支都可用条件语句表达,如下图

分支语句块中包含非常重的计算,导致计算开销远大于对流水线性能的优化

具有一些临界风险情况。如取p指针指向地址的值的操作,必须在p不为0前提下进行。而条件数据传输指令会先将两个结果计算出来,再做取舍。此时若p指针不存在,会报错

计算中可能出现副作用,即使用变量互相间有关联。两种结果均会对x进行更新,若使用条件数据传输指令先计算结果的话,会使x值变化,与原逻辑不符

到此这篇关于汇编语言 跳转指令与C语言的条件分支的文章就介绍到这了,更多相关汇编语言 跳转指令内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 汇编语言:比较指令、跳转指令、JCC的使用

    一.JMP 指令:修改EIP 当前运行的下一条指令 JMP 寄存器/立即数        目标类似:  mov  EIP,寄存器/立即数 CALL指令:  调用函数  CALL 地址A/寄存器        等价:                 PUSH 地址B           :保存call的下一条指令地址,压栈,作为返回值,                MOV EIP,地址A/寄存器            : 将函数首地址作为EIP RET指令:        等价:LEA ESP,

  • 汇编语言 跳转指令与C语言的条件分支

    跳转指令 跳转指令也是一个组的指令,称为j组.其中jmp为无条件跳转,其余为条件跳转 上图为j组指令,可结合条件码访问指令加深理解 在机器指令水平上理解如何对跳转指令编码 如上图,通过反汇编软件得到机器指令与汇编语言,其中左边为机器指令编码,右边为对应汇编语言含义,最左边为每条机器指令地址 jmp指令的对应机器指令有两个字节:eb表示这是jmp指令,03描述跳转信息.值得注意的是,跳转指令进行编码时,采用相对位置编码,如03描述的就是偏移量 结合实例进行理解:在未执行jmp指令时,rip寄存器存

  • 汇编语言入门汇编指令及寄存器详解教程

    目录 前言 什么是汇编语言 汇编语言产生的原因 汇编与二进制的关系 寄存器 寄存器作用 存取速度比较 寄存器分类 常用寄存器用途 寄存器EAX.AX.AH.AL的关系 汇编语言指令 数据传送指令 算术运算指令 逻辑运算指令 循环控制指令 转移指令 linux 和 windows 下汇编的区别 总结 前言 我们大都是被高级语言惯坏了的一代,源源不断的新特性正在逐步添加到各类高级语言之中,汇编作为最接近机器指令的低级语言,已经很少被直接拿来写程序了,不过我还真的遇到了一个,那是之前的一个同事,因为在

  • 汇编跳转指令使用总结

    虽然jmp指令提供了控制转移,但是它不允许进行任何复杂的判断.80x86条件跳转指令提供了这种判断.条件跳转指令是创建循环和实现其他条件执行语句.条件跳转指令检查一个或多个标志位,判断它们是否匹配某个特殊条件(就像setcc指令):如果标志匹配成功,该指令就将控制转移到目标位置:如果匹配失败,CPU忽略该条件跳转指令而继续执行下一条指令.条件跳转指令有一个限制:目标标号的位置必须在跳转指令本身附近32768字节范围内,这通常对应着8000-32000条机器指令.一般情况下不会超过这种限制. 用自

  • 详解C语言中条件判断语句if和switch的用法

    if 语句 用 if 语句可以构成分支结构,它根据给的条件进行判定,以决定执行哪个分支程序段. C 语言的 if 语句有三种基本形式 第一种形式: if(条件表达式) { 语句1: } if(条件表达式) { 语句1: } 这种形式运行顺序为:当条件表达式为真,执行语句1,否则,直接跳过语句1,执行后面的语句. 例子1: BOOL result = YES: if(result) { printf("result is true\n"); } BOOL result = YES: if

  • C语言超细致讲解分支语句

    目录 前言 C语言的语句 爱选择的分支家族 无所不能的大哥if 另辟蹊径的小弟switch 前言 从今天开始,我将不间断的为大家分享我学C的历程,今天为大家分享的是分支语句. C语言的语句 C语句可分为以下五类: 1. 表达式语句 2. 函数调用语句 3. 控制语句 4. 复合语句 5. 空语句 今天我要分享的是:控制语句 那么什么是控制语句呢? 简单来说便是控制程序执行流程的,在C语言中有三大家族. 今天先为大家介绍:爱选择的分支家族,后续将为大家介绍一根筋的循环家族和爱转弯的转向家族. 爱选

  • 手把手带你走进Go语言之条件表达式

    目录 概述 if 语句 switch 语句 概述 Golang 是一个跨平台的新生编程语言. 今天小白就带大家一起携手走进 Golang 的世界. (第 6 课) if 语句 通过一条或多条语句的执行结果来决定执行的代码块. 如图: 格式: if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } else if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } else if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } else { /* 上

  • C语言之选择分支语句详解

    目录 1.if-else语句 1.1 例子与总结 1.2 if与else的配对问题 1.3 if-else代码编写建议 2. switch (case)语句 2.1例子和总结 2.2 switch语句其他知识点 1.if-else语句 1.1 例子与总结 例子: ①只有一个if if (1 == a) { printf("yes\n"); } ②if-else语句 if (1 == a) { printf("yes\n"); } else { printfr(&qu

  • C语言图文并茂讲解分支语句用法

    目录 一.if 语句分析 二.switch 语句分析 三.小结 一.if 语句分析 if 语句用于根据条件选择执行语句 else 不能独立存在且总是与它最近的 if 相匹配 else 语句后可以接连其他 if 语句 if 语句中零值比较的注意点 bool 型变量应该直接出现于条件中,不要进行比较 变量和 0 值比较时,0 值应该出现在比较符号左边(这条规则可以拓展为任意字面量与变量比较时,字面量应该放在左边,变量放在右边,这样即使手误写成了 = ,编译器也能发现) float 型变量不能直接进行

  • 一文搞懂Go语言中条件语句的使用

    目录 if语句 if...else 语句 if 语句嵌套 switch 语句 Type Switch fallthrough select 语句 条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句. Go 语言提供了以下几种条件判断语句: 语句 描述 if 语句 if 语句 由一个布尔表达式后紧跟一个或多个语句组成. if...else 语句 if 语句 后可以使用可选的 else 语句, else 语

随机推荐