[BX]和Loop指令

[BX]和Loop指令

  • 1 描述性符号: “()”
  • 2 idata常量
  • 3 [BX]
  • 4 Loop
  • 5 Debug和汇编编译器masm对指令的不同处理
  • 6 Loop和[BX]的联合应用
  • 7 段前缀

本文属于《 X86指令基础系列教程》之一,欢迎查看其它文章。

1 描述性符号: “()”

我们定义的描述性的符号: "()”,为了描述上的简洁,在以后的课程中,我们将使用一个描述性的符号 “()”来表示一个寄存器或一个内存单元中的内容
比如:(ax)表示ax中的内容、(al)表示al中的内容

  • (20000H)表示内存 20000H 单元的内容(0中的内存单元的地址为物理地址);
  • ((ds)*16+(bx))表示:ds中的内容为ADR1, bx中的内容为ADR2,内存ADR1×16+ADR2单元的内容。也可以理解为: ds中的ADR1作为段地址, bx中的ADR2作为偏移地址,内存ADR1:ADR2 单元的内容。

注意, “()”中的元素可以有 3 种类型:①寄存器名;②段寄存器名; ③内存单元的物理地址(一个20位数据)。
比如:(ax)、(ds)、 (al)、(cx)、 (20000II)、((ds)*161(bx))等是正确的用法;(2000:0)、((ds):1000H)等是不正确的用法。

我们看一下(X)的应用,比如:

  • (1) ax 中的内容为 0010H,可以这样来描述: (ax)=0010H;
  • (2) 2000:1000处的内容为0010H,可以这样来描述: (21000H)=0010H:
  • (3)对于mov ax,[2]的功能,可以这样来描述: (ax)=((ds)*16+2);
  • (4)对于mov [2],ax的功能,可以这样来描述: ((ds)*16+2)=(ax);
  • (5)对于add ax,2的功能,可以这样来描述: (ax)=(ax)+2;
  • (6)对于add ax,bx的功能,可以这样来描述: (ax)=(ax)+(bx);
  • (7)对于 push ax 的功能,可以这样来描述:(sp)=(sp)-2;((ss)*16+(sp))=(ax)
  • (8)对于pop ax的功能,可以这样来描述:(ax)=((ss)*16+(sp));(sp)=(sp)+2

“(X)”所表示的数据有两种类型:①字节;②字。
是哪种类型由寄存器名或具体的运算决定,比如:(al)、(bl)、(cl)等得到的数据为字节型; (ds)、 (ax)、 (bx)等得到的数据为字型。

2 idata常量

我们在Debug中写过类似的指令: mov ax,[0],表示将ds:0处的数据送入ax中。指令中,在"[…]”里用一个常量0表示内存单元的偏移地址。以后,我们用idata表示常量。比如:
mov ax,[idata]就代表mov ax,[1]、 mov ax,[2]、mov ax,[3]等。
mov bx,idata 就代表 mov bx,1、mov bx,2、mov bx,3 等。

3 [BX]

mov ax, [bx]

功能: bx 中存放的数据作为一个偏移地址EA,段地址SA默认在 ds中,将SA:EA处的数据送入ax中。即:(ax)=((ds)*16+(bx))。

mov [bx],ax

功能: bx 中存放的数据作为一个偏移地址EA,段地址SA 默认在 ds 中,将 ax 中的数据送入内存SA:EA处。即:((ds)*16+(bx))=(ax)。

4 Loop

loop指令的格式是: loop 标号。
CPU执行loop指令的时候,要进行两步操作:

  • ①(cx)=(cx)-1;
  • ②判断 cx 中的值,不为零则转至标号处执行程序,如果为零则向下执行。

我们用loop指令来实现循环功能, cx中存放循环次数。
以下 3 条指令:

   mov cx,11
s: add ax,axloop s

执行loops时,首先要将(cx)减1,然后若(cx)不为0,则向前转至s处执行add ax,ax。所以,可以利用cx来控制add ax,ax的执行次数。

从上面的过程中,我们可以总结出用 cx 和 loop 指令相配合实现循环功能的 3 个要点:

  • (1) 在 cx 中存放循环次数;
  • (2) loop指令中的标号所标识地址要在前面;
  • (3)要循环执行的程序段,要写在标号和loop指令的中间。

用cx和loop指令相配合实现循环功能的程序框架如下:

    mov cx,循环次数
s:  循环执行的程序段loop s

5 Debug和汇编编译器masm对指令的不同处理

我们在Debug中写过类似的指令:
mov ax, [0]
表示将ds:0处的数据送入ax中。
但是在汇编源程序中,指令"mov ax,[0]”被编译器当作指令"mov ax,0"处理。

下面通过具体的例子来看一下Debug和汇编编译器masm对形如“mov ax,[0]”这类指令的不同处理。
任务:将内存2000:0、 2000:1、2000:2、2000:3单元中的数据送入al,b1,cl,d1中。
(1)在Debug 中编程实现:

mov ax,2000
mov ds,ax 
mov al, [0]
mov bl, [1]
mov cl, [2]
mov dl, [3]

(2)汇编源程序实现:

assume cs:code 
code segmentmov ax,2000h 
mov ds,ax 
mov al, [0]
mov bl, [1]
mov cl, [2]
mov dl, [3]mov ax,4c00h
int 21hcode ends 
end

我们看一下两种实现的实际实施情况:
(1) Debug中的情况如下图所示。
在这里插入图片描述
(2)将汇编源程序存储为compare.asm,用masm、 link生成compare.exe,用Debug加载compare.exe,如下图所示。
在这里插入图片描述
我们在Debug中和源程序中写入同样形式的指令:“mov al,[0]”、“mov b1,[1]”、“mov cl,[2]” 、“mov d1,[3]” ,但Debug和编译器对这些指令中的"[idata]”却有不同的解释。
Debug将它解释为"[idata]”是一个内存单元,“idata”是内存单元的偏移地址;而编译器将"[idata]”解释为"idata"。

那么我们如何在源程序中实现将内存2000:0、 2000:1、 2000:2、2000:3单元中的数据送入 al,bl,cl,dl 中呢?
目前的方法是,可将偏移地址送入bx寄存器中,用[bx]的方式来访问内存单元。比如我们可以这样访问2000:0单元:

mov ax,2000h
mov ds,ax		;段地址 2000h 送入 ds
mov bx,0		;偏移地址 0 送入 bx
mov al, [bx]	;ds:bx单元中的数据送入al

这样做是可以,可是比较麻烦,我们要用bx来间接地给出内存单元的偏移地址。我们还是希望能够像在Debug中那样,在"[]”中直接给出内存单元的偏移地址。这样做,在汇编源程序中也是可以的,只不过,要在“[]”的前面显式地给出段地址所在的段寄存器。比如我们可以这样访问2000:0单元:

mov ax,2000h
mov ds,ax
mov al,ds:[0]

比较一下汇编源程序中以下指令的含义。

  • “mov al,[0]” ,含义: (al)=0,将常量0送入al中(与mov al,0含义相同);
  • “mov al,ds:[0]” ,含义: (al)=((ds)*16+0),将内存单元中的数据送入al中;
  • “mov al,[bx]” ,含义: (al)=((ds)*16+(bx)),将内存单元中的数据送入al中;
  • "mov al,ds:[bx]” ,含义:与"mov al,[bx]”相同。

从上面的比较中可以看出:
(1)在汇编源程序中,如果用指令访问一个内存单元,则在指令中必须用“[…]”来,表示内存单元,如果在"[]”里用一个常量idata直接给出内存单元的偏移地址,就要在“[]”的前面显式地给出段地址所在的段寄存器。比如:

mov al,ds: [0]

如果没有在“[]”的前面显式地给出段地址所在的段寄存器,比如:

mov al, [0]

那么,编译器masm将把指令中的"[idata]“解释为"idata”。
(2)如果在“[]”里用寄存器,比如bx,间接给出内存单元的偏移地址,则段地址默认在 ds 中。当然,也可以显式地给出段地址所在的段寄存器。

6 Loop和[BX]的联合应用

计算 ffff:0~ffff:b 单元中的数据的和,结果存储在 dx 中。

assume cs:code
code segmentmov ax,Offffhmov ds,axmov bx,0		;初始化 ds:bx 指向 ffff:0mov dx,0		;初始化累加寄存器dx, (dx)=0mov cx,12		;初始化循环计数寄存器cx, (cx)=12s:  mov al, [bx]mov ah,0add dx,ax		;间接向dx中加上((ds) *16+ (bx) )单元的数值inc bx			;ds:bx 指向下一个单元loop smov ax,4c00hint 21hcode ends 
end

加一指令inc:

inc a 		;相当于 add a,1 //i++

减一指令dec:

dec a 		;相当于 sub a,1 //i--

“mov al,[bx]"中的bx就可以看作一个代表内存单元地址的变量,我们可以不写新的指令,仅通过改变bx中的数值,改变指令访问的内存单元。

7 段前缀

指令“mov ax,[bx]”中,内存单元的偏移地址由 bx 给出,而段地址默认在ds中。我们可以在访问内存单元的指令中显式地给出内存单元的段地址所在的段寄存器。比如:

mov ax,ds:[bx]

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ds中。
这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的"ds:" “es:” “ss:” “es:”,在汇编语言中称为段前缀


参考文档:

  • 《汇编语言 第3版》 王爽 清华大学出版社

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

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

相关文章

【web前端】web前端设计入门到实战第一弹——html基础精华

前端 一:图片属性二:音频标签三: 视频标签四:链接标签五:列表标签5.1.无序列表5.2.有序列表3.自定义列表 六:表格6.1合并单元格 七:input标签八:select系列九: 文本域标签…

python元组、拆包和装包

注意 元组不能修改元素 元组:如果元素为字符串且元素为1个,必须加一个, ********* t1 (aa,) 下标和切片 in not in for ... in ... 元组转为列表 拆包、装包

Android DI框架-Hilt

到底该如何理解<依赖注入> 模版代码&#xff1a;食之无味&#xff0c;弃之可惜 public class MainActivity extends Activity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView mTextView(TextView) findVi…

游戏数据分析工具该怎样选择?有哪些选择标准?

选择游戏数据分析工具时&#xff0c;可以考虑以下标准&#xff1a; 1、功能全面性 确保工具提供全面的功能&#xff0c;包括玩家行为分析、性能监测、用户留存率、收入分析等&#xff0c;以满足不同层面的需求。 2、易用性 选择界面友好、易于使用的工具&#xff0c;以确保团…

[PyTorch]即插即用的热力图生成

先上张效果图&#xff0c;本来打算移植霹雳老师的使用Pytorch实现Grad-CAM并绘制热力图。但是看了下代码&#xff0c;需要骨干网络按照标准写法&#xff08;即将特征层封装为features数组&#xff09;&#xff0c;而我写的网络图省事并没有进行封装&#xff0c;改造网络的代价又…

【学习笔记】RabbitMQ-6 消息的可靠性投递2

参考资料 RabbitMQ官方网站RabbitMQ官方文档噼咔噼咔-动力节点教程 文章目录 十一、队列Queue的消息属性11.1 具体属性11.2 自动删除11.2 自定义参数11.2.1 **Message TTL** 消息存活时间11.2.2 **Auto expire** 队列自动到期时间11.2.3 **Overflow behaviour** 溢出行为11.2.4…

微信扫码跳转到小程序内部,浏览器扫码跳转到App 内部,如果手机上没有安装App ,跳转到下载页

第一:微信扫普通二维码跳转到小程序 第一步:登录微信公众平台,左侧点击开发管理,点击开发设置,滑到最下边,找到扫普通链接二维码打开小程序,配置对应的二维码链接,注意要拿这个链接去生成二维码,这样微信扫码才能跳转到小程序内部,还有那个校验文件,让后台放到对应的文件夹下,…

c#是不是比qt好找工作些?

c#是不是比qt好找工作些? C#和Qt都是非常流行的编程语言&#xff0c;会对你未来找工作都有一定的帮助。然而&#xff0c;就目前工作市场而言&#xff0c;C#的相关岗位可能更多一些&#xff0c;因为它被广泛用于企业应用开发和微软生态系统中。最近很多小伙伴找我&#xff0c;说…

python——loguru第三方日志管理模块

loguru第三方日志管理模块 loguru介绍日志等级日志保存日志过滤处理异常 loguru介绍 loguru是第三方库&#xff0c;拿来即用&#xff0c;不用太多的配置 安装&#xff1a;pip install loguru 日志等级 from loguru import loggerlogger.debug(这是一条调试消息&#xff01;)…

SpringBoot面试题2:SpringBoot与SpringCloud 区别?SpringBoot和Spring、SpringMVC的区别

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot与SpringCloud 区别? Spring Boot 和 Spring Cloud 是 Spring 生态系统中的两个关键组件,它们有以下区别: 定位:Spring Boot 用于简…

C# OpenVINO Det 物体检测

效果 耗时 elephant:89% Preprocess: 0.00ms Infer: 47.21ms Postprocess: 11.63ms Total: 58.84ms 项目 代码 using OpenCvSharp; using Sdcb.OpenVINO; using Sdcb.OpenVINO.Natives; using System; using System.Diagnostics; using System.Drawing; using System.Text; …

安科瑞Acrel-7000工业能耗在线监测系统,企业能源管控平台

安科瑞虞佳豪 能源管理系统采用分层分布式系统体系结构&#xff0c;对建筑的电力、燃气、水等各分类能耗数据进行采集、处理&#xff0c;并分析建筑能耗状况&#xff0c;实现建筑节能应用等。通过能源计划&#xff0c;能源监控&#xff0c;能源统计&#xff0c;能源消费分析&a…

“高级小程序开发指南“

目录 引言小程序视图层小程序逻辑层及生命周期总结 引言 随着移动互联网的快速发展&#xff0c;小程序作为一种轻量级的应用形态&#xff0c;在用户使用体验和开发者便捷性方面受到了广泛关注。本篇博客将带你深入探索小程序的视图层和逻辑层&#xff0c;并介绍其生命周期。 …

DTI综述(更新中)

Deep Learning for drug repurposing&#xff1a;methods&#xff0c;datasets&#xff0c;and applications 综述读完&#xff0c;觉得少了点东西&#xff0c;自己写个DTI综述 Databases(包括但不限于文章中的) DATABASEDESCRIBEBindingDB有详细的drug信息和对应的target&a…

需要影视解说配音的看过来,用它就对了

近年来&#xff0c;随着影视、动画等领域的快速发展&#xff0c;声音设计和配音成为了影片制作中不可或缺的一环。然而&#xff0c;并非每个人都拥有天赋般的配音技巧。面对这一困境&#xff0c;幸运的是&#xff0c;现在市面上有很多简单免费好用的配音软件&#xff0c;今天就…

基于B/S架构,包括PC后台管理端、APP移动端、可视化大屏端的智慧工地源码

智慧工地管理平台充分运用数字化技术&#xff0c;聚焦施工现场岗位一线&#xff0c;依托物联网、互联网、AI等技术&#xff0c;围绕施工现场管理的人、机、料、法、环五大维度&#xff0c;以及施工过程管理的进度、质量、安全三大体系为基础应用&#xff0c;实现全面高效的工程…

ant中的environment属性

在ant的配置文件中&#xff0c;可以设置属性environment的值&#xff0c;设置的这个值就作为访问环境变量的前缀。例如声明了environment“env”&#xff0c;那么就可以通过env.<环境变量名称>来访问环境变量。 例如创建了一个Java工程&#xff0c;在工程目录下有一个bu…

2023年震撼!Java地位摇摇欲坠?Java在TIOBE排行榜滑坡至历史最低!

一、Java掉到历史最低 从2023年6月开始Java掉到历史最低排到第4位 2023年10月tiobe编程语言排行榜&#xff0c;Java仍然还是排到了第4位&#xff0c;C# 和 Java 之间的差距从未如此之小。 top 10 编程语言1988年~2023年历史排名 引用tiobe官网上TIOBE Software 首席执行官的话…

[uni-app] canvas绘制圆环进度条

文章目录 需求参考链接基本问题的处理1:画布旋转的问题2:注意arc()的起始位置是3点钟方向3: 如果绘制1.9*Matn.PI的圆环, 要保证其实位置在0点方向?4:小线段怎么画, 角度怎么处理? 源码 需求 要绘制一个如此的进度条 参考链接 uni-app使用canvas绘制时间刻度以及不显示问…

【前端学习】—JS判断数据类型的方式有哪些(八)

【前端学习】—JS判断数据类型的方式有哪些&#xff08;八&#xff09; 一、JS中判断数据类型的场景 二、JS中有哪些数据类型 三、JS判断数据类型的方式有哪些 const arr[]; const object{};const number1; const stringstring;//typeofconst typetypeof arr; console.log(type…