【汇编语言】标志寄存器(三) —— 条件跳转,精准决策:汇编语言的比较与转移

news2025/2/24 12:40:39

在这里插入图片描述

文章目录

  • 前言
  • 1. 检测比较结果的条件转移指令
    • 1.1 什么是条件转移指令?
    • 1.2 两类条件转移指令
  • 2. 根据无符号比较的条件转移指令
    • 2.1 如何记忆?
    • 2.2 如何实现比较转移的功能?
    • 2.3 举例说明
      • 2.3.1 例1
      • 2.3.2 例2
  • 3. 总结
  • 4. 例题巩固
    • 4.1 问题一
      • 4.1.1 问题与思路
      • 4.1.2 问题的分析与解决
    • 4.2 问题二
      • 4.2.1 问题与思路
      • 4.2.2 问题的分析与解决
    • 4.3 问题三
      • 4.3.1 问题与思路
      • 4.3.2 问题的分析与解决
  • 结语

前言

📌

汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。

本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。

下面的内容中我们将学习一些根据cmp指令的比较结果(即,cmp指令执行后,相关标志位的值)进行工作的指令。

1. 检测比较结果的条件转移指令

1.1 什么是条件转移指令?

转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改 IP

比如,jcxz就是一个条件转移指令,它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。

所有条件转移指令的转移位移都是[-128,127],也就是短转移。

除了jcxz之外,CPU还提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。

它们检测的是哪些标志位呢?

就是被cmp指令影响的那些,表示比较结果的标志位。这些条件转移指令通常都和cmp相配合使用,就好像call和ret指令通常相配合使用一样。

1.2 两类条件转移指令

因为cmp指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据cmp指令的比较结果进行转移的指令也分为两种,即:

  • 根据无符号数的比较结果进行转移的条件转移指令(它们检测 zf、cf的值)。

  • 根据有符号数的比较结果进行转移的条件转移指令(它们检测 sf、of和 zf的值)。



🚁🚁🚁

下面将会讲解根据无符号数的比较结果进行转移的条件转移指令。

根据有符号数的比较结果进行转移的条件转移指令的工作原理和无符号的相同,只是检测了不同的标志位。

我们在这里主要探讨的是cmp、标志寄存器的相关位、条件转移指令三者配合应用的原理,这个原理具有普遍性,而不是逐条讲解条件转移指令。对这些指令感兴趣的读者可以查看相关的指令手册。



2. 根据无符号比较的条件转移指令

下面是常用的根据无符号数的比较结果进行转移的条件转移指令。

在这里插入图片描述

2.1 如何记忆?

这些指令比较常用,它们都很好记忆,它们的第一个字母都是j,表示jump;后面的字母表示意义如下。

  • e:表示equal;

  • ne:表示not equal;

  • b:表示below;

  • nb:表示not below;

  • a:表示above;

  • na:表示not above。

2.2 如何实现比较转移的功能?

注意观察一下它们所检测的标志位,都是cmp指令进行无符号数比较时候,记录比较结果的标志位。比如je,检测 ZF位,当 ZF=1的时候进行转移,如果在 je 前面使用了 cmp 指令,那么je对ZF的检测,实际上就是间接地检测cmp的比较结果是否为两数相等

2.3 举例说明

2.3.1 例1

下面看一个例子。

编程实现如下功能:

如果(ah)=(bh)则(ah)=(ah)+(ah),否则 (ah)=(ah)+(bh)。

	cmp ah,bh
	je s
	add ah,bh
	jmp short ok
 s: add ah,ah
ok: ...

上面的程序执行时,如果(ah)=(bh),则 cmp ah,bh 使 zf=1,而 je 检测 zf是否为 1,如果为1,将转移到标号s处执行指令add ah,ah。这也可以说,cmp 比较 ah、bh 后所得到的相等的结果使得je指令进行转移。从而很好地体现了je指令的逻辑含义,相等则转移

虽然 je 的逻辑含义是“相等则转移”,但它进行的操作是,ZF=1时则转移

“相等则转移”这种逻辑含义,是通过和 cmp 指令配合使用来体现的,因为是cmp 指令为“ZF=1”赋予了“两数相等”的含义。

至于究竟在je之前使不使用cmp指令,在于我们的安排。

je检测的是ZF位置,不管 je 前面是什么指令,只要CPU执行je指令时,ZF=1,那么就会发生转移。

2.3.2 例2

比如:

	mov ax,0
	add ax,0
	je s
	inc ax
s:  inc ax

执行后,(ax)=1。add ax,0使得ZF=1,所以je指令将进行转移。

可在这个时候发生的转移的确不带有“相等则转移”的含义。

因为此处的je指令检测到的zf=1,不是由cmp等比较指令设置的,而是由add指令设置的,并不具有“两数相等”的含义。

但无论“zf=1”的含义如何,是什么指令设置的,只要是 zf=1,就可以使得 je 指令发生转移

3. 总结

CPU提供了cmp指令,也提供了 je 等条件转移指令,如果将它们配合使用,可以实现根据比较结果进行转移的功能。但这只是“如果”,只是一种合理的建议,和事实上常用的方法。但究竟是否配合使用它们,完全是你自己的事情。这就好像,call和ret指令的关系一样。

对于jne、jb、jnb、ja、jna等指令和cmp指令配合使用的思想和je相同,可以自己分析一下。

虽然我们分别讨论了cmp指令和与其比较结果相关的有条件转移指令,但是它们经常在一起配合使用。所以我们在联合应用它们的时候,不必再考虑cmp指令对相关标志位的影响和 je 等指令对相关标志位的检测。因为相关的标志位,只是为cmp和je等指令传递比较结果。我们可以直接考虑cmp和je等指令配合使用时,表现出来的逻辑含义。它们在联合使用的时候表现出来的功能有些像高级语言中的IF语句。

4. 例题巩固

data段中的8个字节如下:

data segment 
	db 8,11,8,1,8,5,63,38
data ends

4.1 问题一

4.1.1 问题与思路

(1)编程:统计data段中数值为8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个和8相等的数就将ax的值加1。

4.1.2 问题的分析与解决

程序如下。

		mov ax,data
        mov ds,ax
        mov bx,0             ;ds:bx指向第一个字节
        mov ax,0             ;初始化累加器
        mov cx,0
		
    s:  cmp byte ptr [bx],8  ;和8进行比较
        jne next             ;如果不相等转到next,继续循环
        inc ax               ;如果相等就将计数值加1
		
 next:  inc bx
        loop s               ;程序执行后: (ax)=3

这个程序也可以写成这样:

		mov ax,data
        mov ds,ax
        mov bx,0           	  ;ds:bx指向第一个字节
        mov ax,0        	  ;初始化累加器
        mov cx,0
		
     s: cmp byte ptr [bx],8   ;和8进行比较
        je ok                 ;如果相等就转到ok,继续循环
        jmp short next        ;如果不相等就转到next,继续循环
    ok: inc ax                ;如果相等就将计数值加1
  next: inc bx
        loop s

比起第一个程序,它直接的遵循了“等于8则计数值加1”的原则,用je指令检测等于8的情况,但是没有第一个程序精简。
第一个程序用 jne 检测不等于 8 的情况 ,从而间接地检测等于 8 的情况。
要注意在使用 cmp 和条件转移指令时的这种编程思想。

4.2 问题二

4.2.1 问题与思路

(2)编程:统计data段中数值大于8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个大于8的数就将ax的值加1。

4.2.2 问题的分析与解决

程序如下。

		mov ax,data
        mov ds,ax
        mov bx,0        	 ;ds:bx指向第一个字节
        mov ax,0       		 ;初始化累加器
        mov cx,0
		
     s: cmp byte ptr [bx],8  ;和8进行比较
        jna next        	 ;如果不大于8转到next,继续循环
        inc ax           	 ;如果大于8就将计数值加1
		
 next:  inc bx
        loop s	            

程序执行后:(ax)=3。

4.3 问题三

4.3.1 问题与思路

(3)编程:统计data段中数值小于8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个小于8的数就将ax的值加1。

4.3.2 问题的分析与解决

程序如下。

		mov ax,data
		mov ds,ax
        mov bx,0       		 ;ds:bx指向第一个字节
        mov ax,0       		 ;初始化累加器
        mov cx,0
		
     s: cmp byte ptr [bx],8  ;和8进行比较
        jnb next       		 ;如果不小于8转到next,继续循环
        inc ax         		 ;如果小于8就将计数值加1
		
  next: inc bx
        loop s           	

程序执行后:(ax)=2。

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

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

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

相关文章

【Unity高级】如何获取着色器(Shader)的关键词

在动态设置Shader时,会需要通过EnableKeyword, DisableKeyword来完成。但一个Shader有哪些关键词呢?Unity的文档中并没有列出来,但我们可以通过遍历Shader的KeywordSpace来查看。 1. 代码如下 using UnityEngine;public class KeywordExamp…

针对边缘计算优化LoRa的TinyML信道跳变管道

论文标题:Optimizing LoRa for Edge Computing with TinyML Pipeline for Channel Hopping(针对边缘计算优化LoRa的TinyML信道跳变管道) 作者信息:Marla Grunewald, Mounir Bensalem 和 Admela Jukan,来自德国布伦瑞克…

使用AI工具Screenshot to Code将UI设计图翻译成代码

一、获取openAI apikey。 一般有两种方式,一种是到openAI官网注册账号,付费申请GPT4的apikey。另一种是某宝买代理。我这里采用第二种。 二、安装Screenshot to Code 1.到github下载源码。 2.启动,两种方式:源码启动和docker启动…

python学opencv|读取图像(三)放大和缩小图像

【1】引言 前序已经学习了常规的图像读取操作和图像保存技巧,相关文章链接为: python学opencv|读取图像-CSDN博客 python学opencv|读取图像(二)保存彩色图像-CSDN博客 今天我们更近一步,学习放大和缩小图像的技巧&…

【vue2自定义指令】v-disabled 实现el-switch,el-button等elementUI禁用(disabled)效果

如果你搜过类似的功能,肯定看到过千篇一律的 // 实现按钮禁用el.disabled true// 增加 elementUI 的禁用样式类el.classList.add(is-disabled)但是这个方案明显对el-switch,不起作用,所以我这边直接把方案贴出来,不想了解具体原理…

烟草行业通过Profinet转EthernetIP网关打通数据壁垒

在工业自动化领域,Profinet转Ethernet/IP是两种广泛应用的工业以太网协议。它们各自具有独特的特点和优势,而在实际应用中,经常需要实现这两种协议之间的互通,这时就需要使用到开疆智能Profinet转Ethernet/IP网关KJ-EIP-108。同时…

C++内存布局以及常用关键字

C内存布局以及常用关键字 C的内存空间 代码存储区域:常量区、代码区、静态区(全局区)、堆区、栈区 栈区向下增长,堆区向上增长。栈由系统管理,没有内存碎片,每个元素之间都是连续的,大小比较…

插入排序⁻⁻⁻⁻直接插入排序希尔排序

引言 所谓的排序,就是使一串记录按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 常见的排序算法有: 今天我们主要学习插入排序的直接插入排序和希尔排序。 直接插入排序 什么是直接插入排序? 直接插入排序其…

Python实现中国象棋

探索中国象棋 Python 代码实现:从规则逻辑到游戏呈现 中国象棋,这款源远流长的棋类游戏,承载着深厚的文化底蕴与策略智慧。如今,借助 Python 与 Pygame 库,我们能够在数字世界中复刻其魅力,深入探究代码背后…

2024年12月6日Github流行趋势

项目名称:lobe-chat 项目维护者:arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍:一个开源的现代化设计的人工智能聊天框架。支持多AI供应商(OpenAI / Claude 3 / Gemini / Ollama / Qwen / DeepSe…

FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码:管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码,涵盖了常见的 HTTP 状态码分类,如信息响应(1xx)、成功状态(2xx)、客户端错误&a…

AWS 机器学习,推动 AI 技术的健康发展

目录 一、AI 正在改变生产方式二、从炒作走向务实1、选对场景2、重视数据3、产品思维4、持续优化 三、人才是最稀缺的资源四、负责任的 AI 开发五、未来已来六、启示与思考七、结语 如果说传统软件开发是手工作坊,那么 AI 就像工业革命带来的机器生产。 在最新的一…

OceanBase 的探索与实践

作者:来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题,完整的描述了 OceanBase 的实施落地,通过迁移到 OceanBase 实践案例中遇到的问题与解决方案让大家能更好的了…

Nginx安装和配置详解

1.Nginx的安装 1.1运行以下脚本安装 yum install yum-utils -y rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm# 查看所有可安装nginx版本 yum --showduplicates list available nginx yum install nginx-1.24.0 -y …

up主亲测,ToDesk/青椒云/顺网云这三款云电脑玩转AIGC场景

文章目录 1. 前言2. 云电脑性能分析3. 基础硬件数据3.1 硬件配置3.2 AI 评测跑分 4. 云电脑 AIGC 上手实测4.1 ToDesk4.1.1 AIGC 技术集成情况4.1.2 界面及功能4.1.3 项目部署4.1.4 黑神话悟空 AI 换脸4.1.6 AIGC 文生图体验 4.2 青椒云4.2.1 AIGC 技术集成情况4.2.2 界面及功能…

ARM架构-Cache的底层原理

在主存与处理器之间加入一个小容量的存储器保存 CPU 最近一段时间内的历史访问数据,将在 CPU 发起访问的时候优先提供数据快速访问,这个介于 CPU 与主存储器之间的小容量高速存储空间我们称之为 Cache,即高速缓存。Cache 作为处理器与主存之间…

Codeforces Round 991 (Div. 3) F. Maximum modulo equality(区间gcd模板)

思路&#xff1a;我们由题意可以知道我们只需要维护区间gcd即可&#xff0c;因为差分一下后&#xff0c;维护的差分数组的区间gcd即为原数组所要求的值 线段树维护 #include<bits/stdc.h>using namespace std;typedef long long ll; typedef pair<ll, ll>PII; co…

树与图深度优先遍历——acwing

题目一&#xff1a;树的重心 846. 树的重心 - AcWing题库 分析 采用暴力枚举&#xff0c;试探每个点&#xff0c;除去之后&#xff0c;连通分量最大值是多少&#xff0c; 各个点的最大值找最小的 因为可以通过 dfs 来得到 根u以下点数&#xff0c;以及可以求各分树的点数&am…

消息中间件-Kafka3-kafkaJavaClient小例

消息中间件-Kafka3-kafkaJavaClient小例 Kafak Java Client private static final String KAFKA_TOPIC "kafak-test";private static String bootstrapServers "localhost:9092";private static AdminClient client null;static {Properties config n…

团队管理中如何做好目标管理

团队管理中的目标管理是确保团队高效运行的核心要素之一。 在目标管理中&#xff0c;清晰的目标设定、合理的资源分配、实时的跟踪与反馈机制是成功的关键。首先&#xff0c;设定SMART目标&#xff08;具体、可衡量、可达成、相关性强、时间限定&#xff09;能够有效聚焦团队的…