汇编学习之《jcc指令》

news2025/4/4 21:44:06

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.coloradmin.cn/o/2327450.html

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

相关文章

从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.3.3低代码开发:快速构建行业应用(电商推荐与金融风控案例)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 从零构建大语言模型全栈开发指南-第四部分:工程实践与部署4.3.3 低代码开发:快速构建行业应用(电商推荐与金融风控案例)1. 低代码与AI结合的核心价值2. 电商推荐系统案例2.1 技术架构与实现2.2 性能…

基于vue框架的智能服务旅游管理系统54kd3(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,景点信息,门票预订,酒店客房,客房预订,旅游意向,推荐景点,景点分类 开题报告内容 基于Vue框架的智能服务旅游管理系统开题报告 一、研究背景与意义 1.1 行业现状与挑战 传统系统局限性&#xff1a;当前旅游管理系统普遍存在信息…

用Python实现TCP代理

依旧是Python黑帽子这本书 先附上代码&#xff0c;我在原书代码上加了注释&#xff0c;更好理解 import sys import socket import threading#生成可打印字符映射 HEX_FILTER.join([(len(repr(chr(i)))3) and chr(i) or . for i in range(256)])#接收bytes或string类型的输入…

MySQL的进阶语法7(索引-B+Tree 、Hash、聚集索引 、二级索引(回表查询)、索引的使用及设计原则

目录 一、索引概述 1.1 基本介绍 1.2 基本演示 1.3 特点及优势 二、索引结构 2.1 概述 2.2 二叉树 2.3 B-Tree 2.4 BTree 2.5 Hash 2.5.1 结构 2.5.2 特点 2.5.3 存储引擎支持 三、索引的分类 3.1 索引分类 3.2 聚集索引和二级索引 3.2.1 聚集索引和二级…

【CSS3】04-标准流 + 浮动 + flex布局

本文介绍浮动与flex布局。 目录 1. 标准流 2. 浮动 2.1 基本使用 特点 脱标 2.2 清除浮动 2.2.1 额外标签法 2.2.2 单伪元素法 2.2.3 双伪元素法(推荐) 2.2.4 overflow(最简单) 3. flex布局 3.1 组成 3.2 主轴与侧轴对齐方式 3.2.1 主轴 3.2.2 侧轴 3.3 修改主…

论坛系统的测试

项目背景 论坛系统采用前后端分离的方式来实现&#xff0c;同时使用数据库 来处理相关的数据&#xff0c;同时将其部署到服务器上。前端主要有7个页面组成&#xff1a;登录页&#xff0c;列表页&#xff0c;论坛详情页&#xff0c;编辑页&#xff0c;个人信息页&#xff0c;我…

宠物店小程序怎么做?助力实体店实现营销突破

宠物店小程序怎么做&#xff1f;助力实体店实现营销突破 ——一个宠物店老板的“真香”实战分享 ​一、行业现状&#xff1a;线下宠物店的“流量焦虑”​ 作为开了3年宠物店的“铲屎官供应商”&#xff0c;这两年明显感觉生意难做了&#xff1a;某宝9.9包邮的狗粮、某团“满…

《Mycat核心技术》第21章:高可用负载均衡集群的实现(HAProxy + Keepalived + Mycat)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 星球项目地址&#xff1a;https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…

深度学习Note.5(机器学习.6)

1.Runner类 一个任务应用机器学习方法流程&#xff1a; 数据集构建 模型构建 损失函数定义 优化器 模型训练 模型评价 模型预测 所以根据以上&#xff0c;我们把机器学习模型基本要素封装成一个Runner类&#xff08;加上模型保存、模型加载等功能。&#xff09; Runne…

从零开始设计Transformer模型(1/2)——剥离RNN,保留Attention

声明&#xff1a; 本文基于哔站博主【Shusenwang】的视频课程【RNN模型及NLP应用】&#xff0c;结合自身的理解所作&#xff0c;旨在帮助大家了解学习NLP自然语言处理基础知识。配合着视频课程学习效果更佳。 材料来源&#xff1a;【Shusenwang】的视频课程【RNN模型及NLP应用…

【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的缓存技术:使用 Redis 提升性能

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、开篇整…

华为配置篇-BGP实验

BGP 一、简述二、常用命令总结三、实验 一、简述 IBGP 水平分割&#xff1a;从一个 IBGP 对等体学到的路由&#xff0c;不会再通告给其他的 IBGP 对等体。在一个 AS 内部&#xff0c;路由器之间通过 IBGP 交换路由信息。如果没有水平分割机制&#xff0c;当多个路由器之间形成…

vue element-ui 工程创建

vue element-ui 工程创建 按照步骤 &#xff1a; https://blog.csdn.net/wowocpp/article/details/146590400 创建工程 vue create demo3 cd demo3 npm run serve 在demo3 目录里面 执行如下命令 npm install element-ui -S 然后查看 package.json main.js 添加代码&…

《AI大模型应知应会100篇》第2篇:大模型核心术语解析:参数、Token、推理与训练

第2篇&#xff1a;大模型核心术语解析&#xff1a;参数、Token、推理与训练 摘要 本文将用通俗易懂的语言拆解大模型领域的四大核心概念&#xff1a;参数、Token、训练与推理。通过案例对比、代码实战和成本计算&#xff0c;帮助读者快速掌握这些术语的底层逻辑与实际应用价值…

【28BYJ-48】STM32同时驱动4个步进电机,支持调速与正反转

资料下载&#xff1a;待更新。。。。 先驱动起来再说&#xff0c;干中学&#xff01;&#xff01;&#xff01; 1、实现功能 STM32同时驱动4个步进电机&#xff0c;支持单独调速与正反转控制 需要资源&#xff1a;16个任意IO口1ms定时器中断 目录 资料下载&#xff1a;待更…

Gradle-基础

一.安装 1. 2.配置环境变量 GRADLE_HOME D:\gradle\gradle-5.6.4 GRADLE_USER_HOME D:\gradle\localRepository 3.下载源配置 安装目录下的init.d文件夹里创建一个init.gradle文件&#xff0c;下载顺序从上到下&#xff0c;内容&#xff1…

Anolis系统下安装Jenkins

1.安装java、maven yum install -y java-17-openjdk-devel maven git wget 2.配置环境变量 1.查看java和maven所在目录 [rootlocalhost ~]# which java /usr/bin/java [rootlocalhost bin]# ll /usr/bin/java lrwxrwxrwx 1 root root 22 4月 1 17:20 /usr/bin/java ->…

LabVIEW 调用 Python 函数

此程序是 LabVIEW 调用 Python 函数实现双精度数相加的典型示例。通过 LabVIEW 搭建交互框架&#xff0c;借助 “Open Python Session” 创建 Python 代码运行环境&#xff0c;定位 Python 模块路径后调用 “Add” 函数&#xff0c;最终实现数据处理并关闭会话。整个流程展现了…

视频分析设备平台EasyCVR视频结构化AI智能分析:筑牢校园阳光考场远程监控网

一、背景分析​ 近年来&#xff0c;学校考试的舞弊现象屡禁不止&#xff0c;严重破坏考试的公平性&#xff0c;不仅损害广大考生的切身利益&#xff0c;也在社会上造成恶劣的影响。为有效制止舞弊行为&#xff0c;收集确凿的舞弊证据&#xff0c;在考场部署一套可靠的视频监控…

AWS用Glue读取S3文件上传数据到Redshift,再导出到Quicksight完整版,含VPC配置

1. 项目背景 AWS的官方文档&#xff0c;关于Glue和Vpc配置部分已经比较旧了&#xff0c;按照官方文档配置的流程始终跑不通&#xff0c;花了一番时间和波折后&#xff0c;才终于完整的跑通了。 在数据分析和商业智能&#xff08;BI&#xff09;领域&#xff0c;我们常需要将存…