汇编学习之《jcc指令》

JCC(Jump on Condition Code)指的是条件跳转指令,c++中的就是if-else, while, for 等分支循环条件判断的逻辑。它包括很多指令集,各自都不太一样,接下来我尽量将每一个指令的c++ 源码和汇编代码结合起来看,加深学习映像。

学习这章之前还是要了解 EFL 标记寄存器的知识: 汇编学习之《标志寄存器》-CSDN博客

以上标志寄存器部分重点看下  CF,ZF,SF,OF,PF.

理解下面的意思:

cmp x,y 

x -y ==> 影响 CF, ZF 标记位  

情况1  x == y , 计算结果是0, 那么 ZF == 1

情况2  x > y,  计算结果不是0,那么 ZF == 0

情况3 x <  y , 计算结果不是0,但是会发生错位,所以  ZF != 0  and  CF ==  1

JE/JZ (ZF ==1  )

测试:cmp + je  ==> c++ !=  运算

je: jump if equal   

je: jump if zero

判断 ZF ==1 (cmp 计算的结果是0,两个值相等情况)

je 和 jz 在OD上是一样的, 你可以尝试输入jz,但是OD会将其替换成JE

汇编代码

mov DWORD PTR [ebp-0xc], 0x1
mov DWORD PTR [ebp-0x10],0x2
mov eax,DWORD PTR [ebp-0xc]
cmp eax,DWORD PTR [ebp-0x10] 
je 0x401661 <main()+81>   //变量1 == 变量2则跳转走,c++代码就必须是 变量1 != 变量2

我们解释下上面汇编的代码

第一行: 分配了一个变量地址是ebp-0xc,并赋值是1

第二行: 分配了一个变量地址是ebp-0x10,并赋值是2.

第三行: 将第一个地址的值赋值给EAX 累计寄存器

第四行: EAX累计寄存器的值(也就是第一个变量的值)减去第二个变量的值。如果为0,则EFL的ZF标记就会被设置成1,否则为0

第五行: 判断ZF标记是否是1,如果是则调整到main函数的0x401661位置,准备清理资源退出。

c++ 代码

这里可以对照这个c++代码

#include <iostream>

int main() {

    // JE / ZF 比较相等

    int a = 1;  //mov DWORD PTR [ebp-0xc], 0x1

    int b = 2; //mov DWORD PTR [ebp-0x10],0x2

    //mov eax,DWORD PTR [ebp-0xc]
    //cmp eax,DWORD PTR [ebp-0x10]

    //je 0x401661 <main()+81>

    if(a != b) {

        std::cout << "a == b" << std::endl;

    }

    return 0;

}

上面的例子我们先看了汇编语言, 大家应该会发现一个问题, 汇编中跳转的地方指令是je, 也就是比较的两个对象相等(cmp 指令结果是0, zf==1)情况就跳转走了。

JNE/JNZ (ZF == 0  使用c++ ==)

测试:cmp + jne/jnz => c++  ==  运算

jne: jump if not equal

jnz: jump is not zero

就是判断 ZF == 0 

jne/jnz 是满足zf ==0就跳转,也就是cmp运算结果不是0,也就是两个变量是一定不相等(a  != b)就会跳转, c++分支想执行就必须是和a !=0  条件相反, 那么c++ 代码就必须变成 a == 0

修改后c++ 代码

对应的汇编代码:

可以将JE/JZ 例子中的c++代码改成a == b 就可以看到了。

JB/JNAE/JC (CF == 1 )

测试:cmp + JB/JNAE/JC  ==>  c++  >=  运算

jb: jump if below  (无符号比较 低于)

jnae: jump not above or equal 

jc: jump if is carry

判断 CF == 1

同以上汇编反向推导c++代码:

第一步: 定义一个变量,赋值为2, 我们定义变量名称为a

第二步: 定义一个变量, 赋值为1   我们定义变量名称为b

第三步: 比较两个变量

但是怎么写呢? 我先看看 汇编指令是jb ,按照这个跳转指令的的规则,它是判断CF ==1。如果发生了进位或则错位, CF == 1那么就满足条件,就跳转到mian函数401661的地址处。

要满足这个要求,就必须是变量a小于变量b(a < b),这样减法cmp计算才会发生借位。c++代码这里也就是一个判断条件,返回过来它是不希望跳转走,是希望顺序执行的,那么c++代码就必须和刚刚汇编跳转指令相反,也就是a < b相反, 那么就是 a >= b 

以下是c+代码

JNB / JAE / JNC (CF == 0)

测试:cmp + JNB / JAE / JNC == > c++  <  运算

jnb: jump if not below

jae: jump if above or equal

jnc: jump if not carry

判断 CF == 0

这就简单思考下,我c++代码要怎么改,才能验证 JNB/JAE的指令呢?

首先CF == 0,  说明 cmp 指令没有发生借位,也就是 a >= b 这种情况,那么就会跳转执行,我们c++代码要执行分支内的代码,就是不希望跳转走,所以就必须相反, 那么就是和 a >=  b条件相反,也就是a < b, 那么我改动代码验证下,看看c++代码条件比较语句变成a <  b后, 汇编指令是否是  JNB / JAE / JNC.

改动的c++ 代码

汇编代码确认

以上符合预期

JBE / JNA (CF == 1 or ZF == 1 )

测试:cmp + jbe/jna ==> c++ > 运算

jbe: jump if above or equal   <=  

jna: jump if not above   不大于

判断  CF == 1 or ZF == 1

汇编运算

c++ 代码

JA / JNBE (CF == 0 and ZF == 0)

测试:cmp + ja/jnbe ==> c++ <= 运算

ja:  jump if above    >

jnbe: jump if not below or  equal   不小于不等于

判断 CF == 0 and ZF == 0

汇编代码:

c++代码:

JL / JNGE (SF ≠ OF)

jl: jump if less

jnge: jump if not greater or equal

sf: 当前计算语句是负数,sf =1

of: 当前计算语句发生了溢出  of =1

判断 SF ≠ OF  不同情况分析:

情况1 sf == 1 and  of ==0

SF == 1 计算结果为负数, OF == 0 没有发生溢出

a = -5, b = 3

a - 3 = -8  sf =1  of=0, 但是没有发生溢出。

c++ 代码

这里按照上面我们的理解, 汇编要满足小于就跳转走,那c++ 代码要反着写,变成 >=

对应的汇编

情况2: sf == 0  and of == 1

sf == 0 计算结果不是负数, 但是 of ==1 意思是发生了溢出

在看下面代码前,思考下,什么情况下 cmp 减法操作计算结果不是负数,但是发生了溢出?

以32为举例: 32位有符号的整数表示的数据返回是-2147483648--2147483647

a = -2147483648,  b = 1

a - b = 2147483647 //负溢出了 但是计算结果是正数

所以: sf == 0  and of == 1

c++代码:

对应汇编:

JNL / JGE (SF = OF)

jl: jump if not less

jnge: jump if greater and equal

sf: 当前计算语句是负数,sf =1

of: 当前计算语句发生了溢出  of =1

判断  SF = OF

情况1 结果是负数,并且发生溢出

a = 5, b = 6 

cmp a,b  ==> sf =1, of =1 

c++ 代码

汇编代码:

情况2: 计算结果不是负数,且没有发生溢出。

JLE / JNG ( SF ≠ OF   or   ZF == 1)

jle: jump if less or equal

jng: jump if not greater

判断  (SF ≠ OF)    or   ZF == 1

情况1 sf == 1 and  of ==0

SF == 1 计算结果为负数, OF == 0 没有发生溢出

a = -5, b = 3

a - 3 = -8  sf =1  of=0, 但是没有发生溢出。

c++ 代码

汇编

情况2 ZF == 1

c++

汇编:

JG / JNLE ( SF == OF and ZF == 0)

jg: jump if greater

jnle: jump if not less or equal

判断 (SF == OF) and ZF == 0

 计算结果是负数, 并且发生溢出

a = 2147483647   b = -1

cmp a,b

汇编:

JO (OF = =1)

jo: jump if overflow

判断 OF = =1

溢出情况比较好验证,但是反推c++ 代码我还没有实现,后面生深入了后在来补充。

JNO (OF == 0)

jo: jump if not overflow

判断 OF == 0

反推c++ 代码我还没有实现,后面生深入了后在来补充。

JS (SF == 1)

js: jump if sign

判断 SF == 1

反推c++ 代码我还没有实现,后面生深入了后在来补充。

JNS (SF == 0)

jns: jump if not sign

判断 SF == 0

反推c++ 代码我还没有实现,后面生深入了后在来补充。

JP / JPE (PF ==1)

jp: jump if parity (奇偶校验事件)

jpe: jump if parity Event (奇偶校验事件)

判断  PF ==1 表示数据里面的二进制数,1的个数是偶数的情况

JNP / JPO ( PF == 0)

jnp: jump if not parity

jpo: jump if pariry odd (奇数)

判断   PF == 0 表示数据里面的二进制数, 1的个数是奇数

上一篇: 汇编学习之《jmp, nop指令》

下一篇:汇编学习之《call, return指令》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/75412.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度解析算法之滑动窗口

12滑动窗口—将 x 减到 0 的最小操作数 题目传送门 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 x 。每一次操作时&#xff0c;你应当移除数组 nums 最左边或最右边的元素&#xff0c;然后从 x 中减去该元素的值。请注意&#xff0c;需要 修改 数组以供接下来的操…

[MySQL初阶]MySQL表的操作

MySQL表的操作 1. 创建表2. 查看表结构3. 修改表&#xff08;修改表的属性而非表的数据&#xff09;4. 删除表 1. 创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储…

sqlalchemy详细介绍以及使用方法

SQLAlchemy是一个Python的ORM&#xff08;对象关系映射&#xff09;工具&#xff0c;它允许开发者使用Python代码来操作数据库而不必直接编写SQL语句。SQLAlchemy提供了一种抽象层&#xff0c;使开发者可以通过简单的Python对象来表示数据库表和记录&#xff0c;从而实现对数据…

图解AUTOSAR_SWS_LINDriver

AUTOSAR LIN驱动详解文档 基于AUTOSAR标准的本地互联网络(LIN)驱动程序技术规范解析 目录 1. 概述 1.1 AUTOSAR LIN驱动简介1.2 LIN协议基础2. LIN驱动架构 2.1 类图结构2.2 状态机设计3. LIN帧结构 3.1 基本帧组成3.2 PID结构4. LIN驱动配置 4.1 主要配置参数4.2 配置结构5. L…

《网络管理》实践环节03:snmp服务器上对网络设备和服务器进行初步监控

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 应用拓扑图 3.0准备工作 所有Linux服务器上&#xff08;服务器和Agent端&#xff09;安装下列工具 yum -y install net-snmp net-snmp-utils 保证所有的HCL网络设备和服务器相互间能…

2025年内外网文件交换系统排名分析

在时代&#xff0c;企业的日常运营离不开内外网文件的交换。然而&#xff0c;传统的文件传输方式难以满足企业对多方面的要求。以下是一些备受关注的内外网文件交换系统及其排名分析。 第一名&#xff1a;阳途内外网文件交换系统 阳途内外网文件交换系统是一款专为解决内外网…

【Centos】centos7内核升级-亲测有效

相关资源 通过网盘分享的文件&#xff1a;脚本升级 链接: https://pan.baidu.com/s/1yrCnflT-xWhAPVQRx8_YUg?pwd52xy 提取码: 52xy –来自百度网盘超级会员v5的分享 使用教程 将脚本文件上传到服务器的一个目录 执行更新命令 yum install -y linux-firmware执行脚本即可 …

Qt进阶开发:QDirModel的使用

文章目录 一、QDirModel的基本介绍二、QDirModel的基本使用2.1 在 QTreeView 中显示文件系统2.2 在 QListView 显示当前目录2.3 在 QTableView 中使用 三、QDirModel的常用API1. 构造 & 目录操作1.1 创建 QDirModel1.2 设置根目录 2. 过滤 & 排序2.1 过滤文件类型2.2 设…

牛客 除2问题

除2&#xff01; 贪心堆 让偶数入堆 注意点&#xff1a; 1.判断堆是否为空再进行操作 2. 为了防止超时&#xff0c;我们采取先求和的方式&#xff0c;后面调整之后再减掉&#xff0c;可以节省一次遍历的时间。 3.注意数据范围&#xff0c;要用long long #include<iost…

#MySQL 语句大全(完整实用教程)

&#x1f4cc; MySQL 语句大全&#xff08;完整实用教程&#xff09; &#x1f4cc; 1. 数据库操作 ✅ 创建数据库 CREATE DATABASE mydb; -- 创建名为 mydb 的数据库✅ 使用数据库 USE mydb; -- 选择数据库✅ 删除数据库 DROP DATABASE mydb; -- 删除数据库&#xff08…

万字重谈C++——类和对象篇

什么是类&#xff1f; 在编程中&#xff0c;类是用来创建对象的模板。可以把类看作一个蓝图&#xff0c;它定义了对象的属性&#xff08;特征&#xff09;和方法&#xff08;行为&#xff09;。例如&#xff0c;如果我们有一个“学生”的类&#xff0c;它可能包含学生的名字、…

18认识Qt坐标系

平面直角坐标系(笛卡尔坐标系) 数学上的坐标系 右手坐标系 计算机中的坐标系 左手坐标系 坐标系的原点(0,0) 就是屏幕的左上角 /窗口的左上角 给 Qt 的某个控件,设置位置,就需要指定坐标.对于这个控件来说, 坐标系原点就是相对于父窗口/控件的. QPushButton 的父元素/父控件/父…

量子计算与人工智能的结合:未来科技的双重革命

引言 在过去几十年里&#xff0c;人工智能&#xff08;AI&#xff09;和计算能力的提升一直是推动科技进步的重要力量。然而&#xff0c;随着深度学习和大规模数据处理的发展&#xff0c;传统计算架构的算力瓶颈逐渐显现&#xff0c;人工智能的训练和推理效率受到了限制。在此背…

SEO长尾词优化策略精要

内容概要 长尾关键词优化是SEO策略中实现精准流量捕获的核心环节。本文从定位方法、搜索意图分析、词库构建三个维度切入&#xff0c;系统阐述如何通过数据化工具筛选高转化潜力词&#xff0c;并结合用户行为路径优化内容架构。具体而言&#xff0c;内容将覆盖关键词挖掘工具的…

基于大模型的主动脉瓣病变预测及治疗方案研究报告

目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究意义 二、大模型预测主动脉瓣病变原理 2.1 大模型介绍 2.2 数据收集与处理 2.3 模型训练与优化 三、术前预测与评估 3.1 主动脉瓣病变类型及程度预测 3.2 患者整体状况评估 3.3 手术风险预测 四、术中应用与监测…

进程和内存管理

目录 一.进程的基本信息 1.1进程的定义 1.2进程的特征 1.3进程的组成 1.4线程产生的背景 1.5线程的定义 1.6进程与线程的区别 1.7进程的类别 1.8进程的优先级 1.8.1进程优先级的概念 1.8.2PRI和NI 1.9僵尸进程 1.9.1僵尸进程的定义 1.9.2僵尸进程产生的原因 1.9…

css动态设置div宽高,calc函数

在css中使用calc函数 calc() 是 CSS 中的一种函数&#xff0c;用于动态计算长度值。它允许你在 CSS 属性中进行数学运算&#xff0c;结合不同的单位&#xff08;如 px、%、em 等&#xff09;&#xff0c;从而创建更加灵活和响应式的布局 表达式规则 运算符&#xff1a;支持加…

飞浆PaddlePaddle 猫狗数据大战

猫狗数据大战 1 数据集的准备以及处理操作1.1 数据集1.2 文件解压操作&#xff08;python&#xff09; 1.3 数据的分类1.4 创建训练集和测试集 2 网络构建CNN版本--DeepID 人脸识别网络结构DeepID 与 CNN 网络结构的差异 3 深度学习模型训练和推理的核心设置4 制图5 训练6 预测…

Spring Boot后端开发全攻略:核心概念与实战指南

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、全栈领域优质创作者、高级开发工程师、高级信息系统项目管理师、系统架构师&#xff0c;数学与应用数学专业&#xff0c;10年以上多种混合语言开发经验&#xff0c;从事DICOM医学影像开发领域多年&#xff0c;熟悉DICOM协议及…

PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具

PPT助手&#xff1a;一款集计时、远程控制与多屏切换于一身的PPT辅助工具 &#x1f4dd;&#x1f3a4; 在现代化的演讲和演示中&#xff0c;如何高效地控制PPT进程、保证展示的流畅性与精准性&#xff0c;成为了每个演讲者必须面对的挑战。无论是商务汇报、学术演讲&#xff0…