【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

在这里插入图片描述

文章目录

  • 前言
  • 1. 批量数据的传递
    • 1.1 存在的问题
    • 1.2 如何解决这个问题
    • 1.3 示例演示
      • 1.3.1 问题说明
      • 1.3.2 程序实现
  • 2. 寄存器冲突问题的引入
    • 2.1 问题引入
    • 2.2 分析与解决问题
      • 2.2.1 字符串定义方式
      • 2.2.2 分析子程序功能
      • 2.2.3 得到子程序代码
    • 2.3 子程序的应用
      • 2.3.1 示例1
      • 2.3.2 示例2
  • 3. 寄存器冲突问题的发现与解决
    • 3.1 重看代码
    • 3.2 分析与解决问题
      • 3.2.1 存在的冲突问题
      • 3.2.2 解决方案的探讨
      • 3.2.3 给出解决方案。
      • 3.2.4 子程序的标准框架
      • 3.2.5 改进之前的程序
  • 结语

前言

📌

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

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

1. 批量数据的传递

1.1 存在的问题

前面学习的例程中,子程序 cube 只有一个参数,放在bx中。如果有两个参数,那么可以用两个寄存器来放,可是如果需要传递的数据有3个、4个或更多直至 N个,我们怎样存放呢?

寄存器的数量终究有限,我们不可能简单地用寄存器来存放多个需要传递的数据。对于返回值,也有同样的问题。

1.2 如何解决这个问题

在这种时候,我们将批量数据放到内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序。对于具有批量数据的返回结果,也可用同样的方法。

接下来我们来看下具体的落实……

1.3 示例演示

1.3.1 问题说明

下面看一个例子,

设计一个子程序,功能:将一个全是字母的字符串转化为大写。

这个子程序需要知道两件事,字符串的内容和字符串的长度。

因为字符串中的字母可能很多,所以不便将整个字符串中的所有字母都直接传递给子程序。但是,可以将字符串在内存中的首地址放在寄存器中传递给子程序。因为子程序中要用到循环,我们可以用loop指令,而循环的次数恰恰就是字符串的长度。

出于方便的考虑,可以将字符串的长度放到cx。

capital:	and byte ptr [si],11011111b		;将ds:si所指单元中的字母转化为大写
			inc si							;ds:si 指向下一个单元
			loop capital					
			ret

1.3.2 程序实现

编程:将data段中的字符串转化为大写。

assume cs:code

data segment
  db 'conversation'
data ends

code segment

start:	mov ax,data
      	mov ds,ax
      	mov si,0		;ds:si指向字符串(批量数据)所在空间的首地址
      
      	mov cx,12		;cx存放字符串的长度
		call capital

      	mov ax,4c00h
      	int 21h
		
capital:and byte ptr [si],11011111b
		inc si
		loop capital
      	ret
		
code ends

end start

❗注意:除了寄存器、内存传递参数外,还有一种通用的方法使用栈来传递参数

2. 寄存器冲突问题的引入

2.1 问题引入

设计一个子程序:功能:将一个全是字母,以0结尾的字符串,转化为大写。

2.2 分析与解决问题

2.2.1 字符串定义方式

程序要处理的字符串以0作为结尾符,这个字符串可以如下定义:

db  ‘conversation’,0

2.2.2 分析子程序功能

应用这个子程序 ,字符串的内容后面定要有一个0,标记字符串的结束。

子程序可以依次读取每个字符进行检测,如果不是0,就进行大写的转化,如果是0,就结束处理。

由于可通过检测0而知道是否己经处理完整个字符串 ,所以子程序可以不需要字符串的长度作为参数。

我们可以直接用jcxz来检测0

2.2.3 得到子程序代码

;说明:将一个全是字母,以0结尾的字符串,转化为大写
;参数:ds:si指向字符串的首地址
;结果:没有返回值
capital:mov cl,[si]
		mov ch, 0
		jcxz ok							;如果(cx)=0,结束;如果不是0,处理
		and byte ptr [si], 11011111b	;将ds:si所指单元中的字母转化为大写
		inc si							;ds:si 指向下一个单元
		jmp short capital
     ok:ret

2.3 子程序的应用

来看一下这个子程序的应用。

2.3.1 示例1

要求:将data段中的字符串转化为大写。

assume cs:code
data segment
  db 'conversation',0
data ends

代码段中的相关程序如下。

mov ax,data
mov ds,ax
mov si,0
call capital

2.3.2 示例2

要求:将data段中字符串全部转化为大写。

assume cs:code

data segment
  db 'word', 0
  db 'unix', 0
  db 'wind', 0
  db 'good', 0
data ends

可以看到,所有字符串的长度都是5(算上结尾符0),使用循环,重复调用子程序capital,完成对4个字符串的处理。

完整的程序如下。

code segment
start:	mov ax,data
      	mov ds,ax
      	mov bx,0

		mov cx,4
    s:	mov si,bx
		call capital
		add bx,5
		loop s

      	mov ax,4c00h
      	int 21h

capital:mov cl,[si]
		mov ch, 0
		jcxz ok
		and byte ptr [si], 11011111b
		inc si
		jmp short capital
     ok:ret

code ends

end start

3. 寄存器冲突问题的发现与解决

3.1 重看代码

上面的这个程序在思想上完全正确,但在细节上却有些错误,把错误找出来。

提示:问题在于cx的使用。

思考后看分析。

3.2 分析与解决问题

3.2.1 存在的冲突问题

问题在于cx的使用,主程序要使用cx记录循环次数,可是子程序中也使用了cx,在执行子程序的时候,cx中保存的循环计数值被改变,使得主程序的循环出错

从上面的问题中,实际上引出了一个一般化的问题:子程序中使用的寄存器,很可能在主程序中也要使用,造成了寄存器使用上的冲突

3.2.2 解决方案的探讨

那么如何来避免这种冲突呢?

粗略地看,可以有以下两个方案。

(1)在编写调用子程序的程序时,注意看看子程序中有没有用到会产生冲突的寄存器,如果有,调用者使用别的寄存器;

(2)在编写子程序的时候,不要使用会产生冲突的寄存器。

我们来分析一下上面两个方案的可行性:

(1)这将给调用子程序的程序的编写造成很大的麻烦,因为必须要小心检查所调用的子程序中是否有将产生冲突的寄存器。

比如说,在上面的例子中,我们在编写主程序的循环的时候就得检查子程序中是否用到了bx和cx,因为如果子程序中用到了这两个寄存器就会出现问题。

如果采用这种方案来解决冲突的话,那么在主程序的循环中,就不能使用cx寄存器,因为子程序中已经用到。

(2)这个方案也是不可能实现的,因为编写子程序的时候无法知道将来的调用情况。

可见,我们上面所设想的两个方案都不可行。

我们希望:

  • (1)编写调用子程序的程序的时候不必关心子程序到底使用了哪些寄存器。

  • (2)编写子程序的时候不必关心调用者使用了哪些寄存器。

  • (3)不会发生寄存器冲突。

3.2.3 给出解决方案。

解决这个问题的简捷方法是,在子程序的开始将子程序中所有用到的寄存器中的内容都保存起来,在子程序返回前再恢复。可以来保存寄存器中的内容

3.2.4 子程序的标准框架

以后,我们编写子程序的标准框架如下:

在这里插入图片描述

3.2.5 改进之前的程序

我们改进一下子程序 capital的设计:

capital: push cx
		 push si

 change: mov cl,[si]
		 mov ch, 0
		 jcxz ok
		 and byte ptr [si], 11011111b
		 inc si
		 jmp short capital
     
     ok: pop si
     	 pop cx
     	 ret

要注意寄存器入栈和出栈的顺序。

结语

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

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

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 泛型详细解析

泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair&#xff0c;它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型&#xff0c;比如下面所示&#xff0c;就指定了实际类型为 LocalDate…

Python语法基础(四)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 高阶函数之map 高阶函数就是说&#xff0c;A函数作为B函数的参数&#xff0c;B函数就是高阶函数 map&#xff1a;映射 map(func,iterable) 这个是map的基本语法&#xff0c;…

【JavaEE初阶】应是天仙狂醉,乱把白云揉碎 - (重点)线程

本篇博客给大家带来的是线程的知识点, 由于内容较多分几天来写. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ⭐欢迎大家点赞 评论 收藏 分享 ❤❤❤ 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 1. 认识线程 1.1 概念 )1 …

构建鸿蒙5.0应用(一)

准备工作 1、开发工具 开发工具使用华为官方推荐的IDE&#xff1a;DevEco Studio &#xff0c;为鸿蒙应用开发提供了最全面的官方支持&#xff0c;包括最新的 SDK、API 和功能。 2、编译工具 开发鸿蒙应用需要安装Nodejs环境&#xff0c;为打包编译鸿蒙应用提供支持&#x…

【Linux】匿名管道通信场景——进程池

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

FUSU: 多源多时相土地利用变化分割数据集

FUSU是首个针对细粒度城市语义理解的多时态、多源地类变化分割数据集&#xff0c;其提供高分辨率双时态图像和每月时序观测&#xff0c;支持对城市动态变化的高频率监测。FUSU-Net是统一的时序架构&#xff0c;可同时进行变化检测和分割任务。结合光学和SAR数据&#xff0c;通过…

LLM学习笔记(13)分词器 tokenizer

由于神经网络模型不能直接处理文本&#xff0c;因此我们需要先将文本转换为数字&#xff0c;这个过程被称为编码 (Encoding)&#xff0c;其包含两个步骤&#xff1a; 使用分词器 (tokenizer) 将文本按词、子词、字符切分为 tokens&#xff1b;将所有的 token 映射到对应的 tok…

Unity中让光点跟图片填充区的末尾一起移动

一、实现效果展示 想要实现的效果如下,就是要让白色光点图片跟随绿色圆形图片填充区末尾一起移动。 二、代码如下: using UnityEngine; using System.Collections; using UnityEngine.UI; using DG.Tweening;public class IconCircle : MonoBehaviour {public float ti…

给定一个整数可能为正,0,负数,统计这个数据的位数.

题目描述 给定一个整数可能为正,0,负数,统计这个数据的位数. 例如1234567输出7位; -12345678输出8位;0输出1位 代码实现 int main() { long long m; long long n; scanf("%lld",&n); mn; int count0;//位数 do { count; n/10;//舍弃个位 }while(n!0); printf(&…

LLamafactory API部署与使用异步方式 API 调用优化大模型推理效率

文章目录 背景介绍第三方大模型API 介绍LLamafactory 部署API大模型 API 调用工具类项目开源 背景介绍 第三方大模型API 目前&#xff0c;市面上有许多第三方大模型 API 服务提供商&#xff0c;通过 API 接口向用户提供多样化的服务。这些平台不仅能提供更多类别和类型的模型…

【关闭or开启电脑自带的数字键盘】

目录 一、按数字键盘左上角的按键【NumLK Scroll】 二、修改注册表中数字键盘对应的数值【InitialKeyboardIndicators】 1、步骤&#xff1a; 2、知识点&#xff1a; 一、按数字键盘左上角的按键【NumLK Scroll】 这是最简单快捷的方法。 关闭后若想开启&#xff0c;再按一…

【FAQ】使用Node.js 镜像 构建本地项目

在nodejs官方并没有提供使用node.js构建本地项目的方法&#xff0c;但是通过阅读官方文档&#xff0c;可以发现&#xff0c;官方在包管理器界面提供了如下语句 所以node.js容器是可以执行语句的 下面通过docker 的 -w 、-v 参数设置容器工作目录和目录映射&#xff08;实现本…

深度学习 | pytorch + torchvision + python 版本对应及环境安装

Hi&#xff0c;大家好&#xff0c;我是半亩花海。要让一个基于 torch 框架开发的深度学习模型正确运行起来&#xff0c;配置环境是个重要的问题&#xff0c;本文介绍了 pytorch、torchvision、torchaudio 及 python 的对应版本以及环境安装的相关流程。 目录 一、版本对应 二…

4399大数据面试题及参考答案(数据分析和数据开发)

对数据分析的理解 数据分析是一个从数据中提取有价值信息以支持决策的过程。它涵盖了数据收集、清洗、转换、建模和可视化等多个环节。 首先&#xff0c;数据收集是基础。这包括从各种数据源获取数据&#xff0c;例如数据库、文件系统、网络接口等。这些数据源可以是结构化的数…

fastdds:编译、安装并运行helloworld

fastdds安装可以参考官方文档&#xff1a; 3. Linux installation from sources — Fast DDS 3.1.0 documentation 从INSTALLATION MANUAL这一节可以看出来&#xff0c;fastdds支持的操作系统包括linux、windows、qnx、MAC OS。本文记录通过源码和cmake的方式来安装fastdds的…

Istio笔记01--快速体验Istio

Istio笔记01--快速体验Istio 介绍部署与测试部署k8s安装istio测试istio 注意事项说明 介绍 Istio是当前最热门的服务网格产品&#xff0c;已经被广泛应用于各个云厂商和IT互联网公司。企业可以基于Istio轻松构建服务网格&#xff0c;在接入过程中应用代码无需更改&#xff0c;…

ipad项目 蓝湖宽度

ipad项目 横屏状态时 蓝湖宽度设置930px media screen and (orientation: portrait) {/* 竖屏时的样式 */ } media screen and (orientation: landscape) {/* 默认是 横屏时的样式 */ }

14、保存与加载PyTorch训练的模型和超参数

文章目录 1. state_dict2. 模型保存3. check_point4. 详细保存5. Docker6. 机器学习常用库 1. state_dict nn.Module 类是所有神经网络构建的基类&#xff0c;即自己构建一个深度神经网络也是需要继承自nn.Module类才行&#xff0c;并且nn.Module中的state_dict包含神经网络中…

在鸿蒙应用中 Debug 对开发者的帮助

文章目录 摘要引言Debug 的意义与挑战案例&#xff1a;页面渲染性能优化中的 Bug 排查Debug 过程详解问题定位问题解决优化布局与渲染逻辑 代码详细讲解示例代码详细讲解1. 导入必要模块2. 数据生成3. 使用虚拟列表组件items 属性itemHeight 属性renderItem 属性 4. 返回完整组…

基于多VSG独立微网的多目标二次控制MATLAB仿真模型

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 本文将一致性算法引入微电网的二次频率和电压控制&#xff0c;自适应调节功率参考值和补偿电压&#xff0c;同时实现频率电压恢复、有功 无功功率的比例均分以及功率振荡抑制&#xff0c;提高系统的暂态和稳…