汇编学习教程:寻址大总结

news2024/11/27 10:36:49

前言

在上篇博文中,我们主要学习了一个全新的寄存器:bp。bp 寄存器在功能和使用上与 bx 有着异曲同工之妙,只不过两人绑定的服务对象不同:bx 默认绑定的是 DS 段寄存器,而 bp 默认绑定的是 SS 段寄存器。bx 和 bp 有着相同的灵活寻址,但是两者却不能组合在一起使用,所以我们确认 bp 是  bx 的兄弟,而不是伙伴。

截至到此,目前我们基本把已有的灵活寻址给学习完了,本篇博文中将主要对已学过的灵活寻址做一个归纳总结,加深我们的学习印象,下面就让我们赶快开始本篇的学习吧!

BX和他的伙伴们

首先要隆重请出最主要的人:bx!

BX

bx 做为一个通用寄存器,已经是我们老熟人了,这里不再作过多的介绍。这里我们要明白的是,在汇编编程中,bx 和 [bx] 之间的区别。

在汇编指令中,bx只是一个存储数据的地方,例如指令:mov ax,bx,就是把bx寄存器中的值赋值到ax寄存器内,执行完毕后,ax寄存器中的值就是bx寄存器中的值;指令:mov bx,ax,则是把ax寄存器中的值赋值到bx寄存器,执行完毕后,bx寄存器中的值就是ax寄存器中的值。由此可见,汇编指令中的 bx 用法,只是充当一个数据存储角色。

但是当bx穿上马甲,变身为 [bx],事情就变得不一样了起来~例如指令:mov ax,[bx],则是将内存地址为 ds:bx 下的一个字数据送入ax寄存器内,此时bx的值就是一个偏移地址,而ds寄存器中的值就是数据段段地址,ds和bx相互配合完成了寻址操作。

总结:

1、在汇编语句中,bx的作用则是一个数据存储器,存放一个字的数据或者一个字节的数据,指令操作的是bx寄存器内的数据

2、在汇编语句中,[bx] 的作用则是代表内存中的一处内存地址,此时bx内的数据值表示偏移值。CPU会默认将DS寄存器中值当作数据段段地址,与bx寄存器中的值合成一个20位的内存地址进行寻址。指令操作的是内存地址 ds:bx 下的数据。

3、[bx] 是和 DS 寄存器强关联关系,CPU会默认段地址为DS寄存器中的值,偏移地址为 bx 寄存器中的值。例如指令你可以这样写:mov ax,[bx],或者写成:mov ax,ds:[bx],这样都是可以的。

4、必须是 [bx],[bl] 是错误的

idata

这是bx的第一个小伙伴,idata,它在汇编编程中表示一个立即数,也就是一个常量,在程序运行的过程中无法改变其值。例如指令:mov ax,idata,意思为将ax寄存器的值赋值为idata,执行完毕后,ax寄存器中的值就是idata。

做为bx的小伙伴,bx可以穿马甲,idata当然也是可以穿上马甲的,成为 [idata]!在汇编语句中,[idata] 的作用基本和 [bx] 一致,唯一区别是由于 idata是一个立即数常量,程序运行中无法修改,所以 [idata] 在程序整个运行周期中,始终表示一个偏移地址。例如指令:mov ax,[idata],意思为将段地址为ds寄存器的值、偏移地址为idata 下的一个字数据送入ax寄存器中。

不过这里有一个注意点,在此前的博文中已经提及过,有忘记的伙伴可以回头温故一下:【bx的作用】,那就是debug工具和masm工具两者对 [idata] 的理解、处理不同。

在debug工具中你可以直接使用 [idata] 的形式,但是在写源代码的时候,则不能直接使用 [idata],因为masm工具对于 [idata] 这种形式只会编译成一个立即数 idata,而不是认为这是一个偏移地址。为了让masm准确编译,我们需要加上强指定,即在源程序中使用:ds:[idata],这样告诉masm这是一个偏移地址,才能准确编译。

总结:

1、在汇编语句中,idata 表示为一个自然数、常量,程序运行期间无法动态修改。

2、在汇编语句中,[idata] 的作用和 [bx] 相似,也是表示一个内存地址,段地址默认是DS寄存器中的值,由于 idata 无法动态修改,所以在整个程序运行周期内,[idata] 始终表示同一个内存地址。

3、Debug工具使用A命令写入汇编指令,支持 [idata] 格式;使用文本编译器写源程序,用masm工具编译时,则源程序内 [idata] 格式编译后 与 idata 表示效果一致,都是表示一个自然数常量,源程序内 段寄存器:[idata] 格式编译后才能正确表示这是一个内存地址。

si、di

下面我们就要介绍bx的两个小跟班,si 和 di。si 和 di 它俩是一对孪生兄弟,也就是说 si 和 di 两者拥有相同的定位和属性,他们两个主要是为了数据复制场景设计的,si的“s”是英文单词“source”,意思“来源”,所以数据复制场景中 si 通常是源数据的偏移地址;di的“d”是英文单词“destination”,意思“目的地”,所以数据复制场景中 di 通常是目的数据的偏移地址

做为bx的伙伴,大家都是可以穿马甲的,所以 si di 都可以穿上马甲成为 [si]、[di]。在汇编语句中,[si] 和 [di] 效果一致,与 [bx]效果同样保持一致。我们可以这样理解,除去数据复制这种场景外,si、di 等同于 bx 寄存器,拥有和 bx 一样的属性和能力

不过有一点例外的是,si、di 不属于通用寄存器,所存储的数据长度固定为一个字,不能向下兼容 8位的字节数据,只能是一个16位寄存器。而bx既可以当成一个16位寄存器,也可以向下兼容8位字节,拆分成两个8位寄存器:bl、bh。

总结:

1、在汇编语句中,si、di 的作用是一个数据存储器,只能存放一个字长度的数据

2、在汇编语句中,[si]、[di] 表示一个内存地址,其中偏移地址为 si、di 中的值,段地址默认是DS寄存器中的值
3、数据复制场景下,si 表示源数据的偏移地址,di 表示目的数据的偏移地址

组合变化

介绍完bx和它的伙伴们,那么接下来我们需要讲一下他们之间友谊,也就是它们相互配合可实现的灵活寻址方式。

[bx+idata]

首先让我们通过 [bx+idata] 寻址方式来回顾 bx 和 idata 之间的友谊~

 在汇编语句中,[bx+idata] 表示为一处内存地址,该内存地址的偏移地址为 bx 寄存器中的值加上一个自然数idata,段地址默认为DS寄存器中的值。

由于idata在程序运行中无法修改,所以在该寻址方式中,idata 的值通常表示为是需要寻址的一段连续内存的起始位置,而 bx 的值则通常为这段连续内存的偏移位置。此寻址方式特性,和 c 语言中的数组是非常相似的,idata 相当于数组中下标为0的元素的地址bx 相当于数组的下标,通过修改下标值即可访问到数组中的任一元素。所以我们也可以将 [bx+idata] 寻址方式看作是一个一维数组

总结:

1、mov ax,[bx+idata],含义为:将偏移地址为 bx寄存器中的值加上一个立即数idata,段地址为DS寄存器中的值的内存地址下的一个字的数据,送入ax寄存器中

2、idata 表示为一段连续内存的起始地址,bx 则表示为这段连续内存上的偏移位置

3、[bx+idata] 寻址方式实现了类似C语言中一维数组的数据访问

[si+idata]

能和idata一起玩耍的当然不止bx一个人,si、di 都能和idata一起玩耍!

寻址方式为:[si+idata]、[di+idata]。由于 si、di 和 bx 的功能属性很相似,所以 [si+idata] 也拥有和 [bx+idata] 同样的效果,也是实现了一维数组的数据访问。这里不再过多赘述,大家参考 [bx+idata] 寻址方式即可。

[bx+si]

好朋友当然一起玩耍才更加尽兴,bx 可以和 si 或者 di 组合一起,成为一个更为灵活的寻址方式,即:[bx+si]、[bx+di]。

在汇编语句中,[bx+si] 也表示一处内存地址,该内存地址的偏移地址为 bx 寄存器中的值加上 si 寄存器中的值,段地址默认为DS寄存器中的值。因为 bx 寄存器的值和 si 寄存器、di 寄存器的值能在程序运行过程中实时修改,所以 [bx+si]、[bx+di] 的寻址形式要比 [bx+idata] 寻址形式更加灵活

由于该寻址方式中,bx、si 都可以在程序运行中实时修改,所以 [bx+si] 通常被用来实现一个二维数组的寻址。bx 用来指向每行的起始位置,si 则用来指向每行数据中的偏移位置,你也可以理解为 bx 用来定位行,si 用来定位列。

总结:

1、mov ax,[bx+si],含义为:将偏移地址为 bx 寄存器中的值加上 si 寄存器中的值,段地址为DS寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

2、[bx+si]、[bx+di] 的寻址方式灵活程度要比 [bx+idata] 寻址方式高

3、[bx+si]、[bx+di] 寻址方式实现了类似C语言中二维数组的数据访问通常情况下,bx 用来指向二维数组中的行,si 或者 di 用来指向二维数组中的列

[bx+si+idata]

玩耍并不尽兴,一起开趴体才更加自在!bx 和它的小伙伴们一起玩耍,来一个大轰趴:[bx+si+idata]、[bx+di+idata]。

在汇编语句中,[bx+si+idata] 同样表示一处内存地址,该内存地址的偏移地址为 bx 寄存器中的值加上 si 寄存器中的值,再加上一个立即数 idata 的值,段地址默认为DS寄存器中的值。因为该寻址方式包含了 bx、si 或者 di ,在程序运行中都可以动态实时修改,所以 [bx+si+idata] 的寻址方式通常也被用来实现一个二维数组的寻址,相比 [bx+si] 寻址方式,由于立即数 idata 的加入,所以在寻址灵活程度上又提高了一点

但是立即数idata并不能在程序运行中实时修改,所以寻址灵活程度提高并不是很大。[bx+si+idata] 寻址方式中 idata 主要作用用来充当每行数据的起始地址,这样做可以保证 bx、si 初始值为0,符合汇编开发的要求规范。对此有不解的小伙伴可以回顾上篇博文【灵活寻址 四】,来加深理解。

总结:

1、mov ax,[bx+si+idata],含义为:将偏移地址为 bx 寄存器中的值加上 si 寄存器中的值,再加上一个立即数 idata 的值,段地址为 DS 寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

2、[bx+si+idata]、[bx+di+idata] 的寻址方式灵活程度要比 [bx+idata] 寻址方式稍高

3、[bx+si+idata]、[bx+di+idata] 的寻址方式同样实现了类似C语言中二维数组的数据访问

4、idata 主要作用是定义每行数据的起始偏移位置,这样做能够保证 bx、si 或者 di 初始值为0,符合开发规范

BX 的兄弟 BP

bp 做为 bx 的兄弟,两者存在相同的灵活寻址形式。这里不再做过多讲述,简单做个总结:

总结:

1、mov ax,[bp],含义为:将偏移地址为 bp 寄存器中的值,段地址为 SS 寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

2、mov ax,[bp+idata],含义为:将偏移地址为 bp 寄存器中的值加上一个立即数 idata,段地址为 SS 寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

3、mov ax,[bp+si],含义为:将偏移地址为 bp 寄存器中的值加上 si 寄存器中的值,段地址为 SS 寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

4、mov ax,[bp+si+idata],含义为:将偏移地址为 bp 寄存器中的值加上 si 寄存器中的值,再加上一个立即数 idata 的值,段地址为 SS 寄存器中的值的内存地址下的一个字数据,送入 ax 寄存器中

绑定的段寄存器

bx 默认绑定的是 DS 段寄存器,但并不是只能是 DS 段寄存器,还可以是 ES 段寄存器、CS 段寄存器、SS 段寄存器。要想让 bx 与 ES、CS、SS 搭上关系,我们需要在汇编指令中使用强指定的手段,才可以使用。强指定形式为:段寄存器:[bx],不过需要注意的是,强指定的形式仅 MASM 工具支持,Debug 工具是不支持的

示例

这里我们打开 Debug,使用 A命令插入以下指令:mov ax,cs:[bx]、mov ax,ss:[bx]、mov ax,ds:[bx]、mov es:[bx],看是否通过:

可以看到,上述四条使用强指定的汇编语句,均未通过。

那么,下面我们使用 Notepad++  编写汇编,使用 MASM 工具编译,看是否编译通过,代码如下:

assume cs:code

code segment
    start:
	    mov ax,cs:[bx]
        mov ax,ss:[bx]
        mov ax,ds:[bx]
        mov ax,es:[bx]
		
        mov ax,4c00H
		int 21H
code ends
end start

 编译结果如下:

 可以看到正常通过编译,那么接下来我们链接生成 exe 文件,使用 Debug 工具查看编译生成的汇编指令:

加载 exe 文件后,我们使用 U 指令查看 076a:0~10 空间内的汇编指令,如上图所示。

 从图中我们可以看到编译的区别:虽然都是使用的强指定形式,但是 mov ax,ds:[bx] 指令编译后,指令前并未出现 DS: 。而其他的指令,例如 mov ax,cs:[bx],指令前出现了 CS:,表示下面的 [bx] 偏移位置为 CS 代码段中。

之所以会出现这样的不同是因为,[bx] 默认绑定的段寄存器就是 DS,也就是说指令:mov ax,ds:[bx] 是等同于指令:mov ax,[bx]。那么 MASM 工具编译的时候,碰到 ds:[bx],就自动省略掉 ds:,将其当作 [bx] 来编译看待,所以我们查看编译后的指令,自然 MOV 指令前没有了 DS:。

错误的寻址

接下来我们说一下错误的寻址方式。

si、di

si 寄存器、di 寄存器他们两个虽然是一对亲兄弟,但是他们两个却是无法在一起使用,一旦相见就像是仇人相见分外眼红一般,无法共存。这里我们直接打开 debug 程序,使用A命令写入下面这条汇编语句:mov ax,[si+di],看下是否通过:

 从上图中可以看到,debug 直接提示了错误,也就是说 si、di 在寻址中是无法共同存在的。

那么也就意味着,以下几条汇编语句都是错误的:

1、mov ax,[si+di]

2、mov ax,[bx+si+di]

3、mov ax,[idata+si+di]

4、mov ax,[bp+si+di]

以上汇编语句所犯错误之处都是出现了 si、di 共存,这在汇编中是不允许的。

bx、bp 

 正所谓一山不容二虎,bx 寄存器和 bp 寄存器同样无法一起共存。在 debug 程序中使用 A 命令写入下面这条汇编语句:mov ax,[bx+bp],观察是否通过:

我们可以看到 debug给出了错误提示,提示我们该语句不符合规则。

那么也就意味着,以下几条汇编语句都是错误的:

1、mov ax,[bx+bp]

2、mov ax,[bx+bp+idata]

3、mov ax,[bx+bp+si]

4、mov ax,[bx+bp+di]

以上汇编语句所犯错误之处都是出现了 bx、bp 共存,这在汇编中是不允许的。

总结

这里贴出一张寻址全家福:

这张图里详细展示了目前我们已经学习过了所有灵活寻址方式,大家在后面的汇编开发中可以参考学习。

本篇结束语

本篇主要是对过往我们学习过的灵活寻址方式进行一个归纳总结,从而加深我们的印象。在后面的编程实例中,我们将会对众多灵活寻址进行实战演练,并逐步掌握不同的开发场景应对不同的寻址方式。

感谢围观,转发分享请标明出处,谢谢~

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

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

相关文章

抓包!抓包! HTTPS中间人抓包

简介 抓包是一种网络分析技术,可以用于捕获和分析数据包,通常用于网络故障排查、协议分析、安全审计等。网络上所有的数据包都是以二进制的形式在网络上传输的,抓包工具可以捕获到这些数据包并将其转换为可读的格式,方便进行分析…

Python使用阿里API进行身份证识别

Python使用阿里API进行身份证实名认证 1. 作者介绍2. 身份证识别介绍3. 调用阿里智能云API4. 代码解析4.1 完整代码4.2 实验结果 参考 1. 作者介绍 孟莉苹,女,西安工程大学电子信息学院,2021级硕士研究生,张宏伟人工智能课题组 研…

极致呈现系列之:Echarts折线图的视觉冲击力

目录 认识折线图折线图的创建折线图的美化修改折线的样式修改坐标轴的样式修改折线图上点的样式将折线设置为平滑曲线设置渐变色面积给折线图添加标记线给折线图添加标记点 折线图的交互添加鼠标悬停提示添加数据区域选择与缩放 认识折线图 折线图是一种常用的数据可视化图表&…

React中的HOC高阶组件处理

先了解函数柯里化 柯里化函数(Currying Function)是指将一个接受多个参数的函数转化成一系列只接受单个参数的函数,并且返回接受单个参数的函数,达到简化函数调用和提高可读性的目的。 简单来说,柯里化即将接收多个参…

大数据为什么如此重要?

简单来说,大数据就是结构化的传统数据再加上非结构化的新数据。那么传统数据和新数据又是什么呢?传统数据就是IT业务系统里面的数据,如客户资料、财务数据等。这些数据是结构化的,量也不是特别大,一般只是TB级。对比传…

如何让自己的代码顺利通过代码审查?

最近很多同学,都去暑期实习了,实习就意味着要在公司项目是写代码了。 大多数同学,可能面试能力不错,但是实操还是弱了一些。之前有位同学,春招靠面试能力去了大厂,然后实习刚工作的时候,要写代…

Java30天拿下-----第二天(运算符,标识符,Scanner,进制转换)

Java30天拿下-----第二天 一 运算符算术运算符赋值运算符关系运算符逻辑运算符三元运算符运算符的优先级 二 标识符关键字保留字 三 控制台接收键盘输入:Scanner四 进制进制的转换(基本功)其他进制转为十进制十进制转为其他进制二进制转为其他…

《当我谈跑步时,我谈些什么》痛楚难以避免,而磨难可以选择

《当我谈跑步时,我谈些什么》痛楚难以避免,而磨难可以选择 村上春树,日本当代小说家,情感类类型作家。主要作品有《且听风吟》《挪威的森林》《海边的卡夫卡》《奇鸟行状录》《1Q84》等。 施小炜 译 来自百度百科的一条&#xff1…

存储快速入门——【2】数据复制与容灾、云存储、大数据概念

存储快速入门——【2】数据复制与容灾、云存储、大数据概念 一、数据复制与容灾 1 恢复时间目标(RTO)和恢复点目标(RPO) 对于信息系统而言,容灾就是使信息系统具有应对一定的灾难袭击,保持系统或间断运行…

2023年软件测试工程师,初级到高级进阶路线指南,测试之路...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 提到软件测试工程…

一、JavaScript函数this指向

1 this的绑定规则 2 apply/call/bind 3 this绑定优先级 4 绑定之外的情况 5 箭头函数的使用 6 this面试题分 <script>// 定义函数function foo(name) {console.log("foo函数:", this)}// 1.方式一: 直接调用 这里的this指向window// foo()// 2.方式二: 通…

Java网络编程知识

目录 1.网络编程概述 1.网络编程的目的 2.网络编程的三个问题 1.如何准确定位网络上的主机&#xff1f; 2.如何定位主机上的特定应用&#xff1f; 3.找到主机后如何可靠高效的进行数据传输&#xff1f; 2.通信要素一:IP和端口号 1.IP地址 2.端口号 3.套接字 4.通信要…

基于Yolov8的纸箱破损检测系统

目录 1.Yolov8介绍 2.纸箱破损数据集介绍 2.1数据集划分 2.2 通过voc_label.py得到适合yolov8训练需要的 2.3生成内容如下 3.训练结果分析 4. 纸张破损检测系统设计 4.1 PySide6介绍 4.2 安装PySide6 4.3 纸张破损检测系统设计 1.Yolov8介绍 Ultralytics YOLOv8是Ultral…

SpringBoot动态加载jar包中的bean

一、业务场景 在有些业务场景下&#xff0c;需要SpringBoot来动态加载jar中的class文件&#xff0c;自动往spring容器中添加新的bean&#xff1b;如物联网设备上传的信息用物模型来解析&#xff0c;用java来解析物模型&#xff0c;但用户的设备千差万别&#xff0c;解析设备的…

系统移植 搭建nfs服务器,启动盘,内核安装和加载

目录 1. nfs 服务器网络环境搭建 1.1. 查看是否安装了 nfs 服务器 1.2. 修改nfs配置文件 1.3. 创建nfs工作目录 1.4. 重启nfs服务 1.5. 开始测试是否成功 2. SD 卡启动盘 2.1. 方法1&#xff1a;从0扇区开始烧写 2.2. 方法2&#xff1a;直接部署 3. Linux 内核的安装…

SpringBoot编程---Day 01

目录 一、springboot介绍 &#xff08;一&#xff09;Spring Boot 特性 &#xff08;二&#xff09;了解自动配置原理 &#xff08;三&#xff09;springboot 入口功能详解 &#xff08;四&#xff09;自定义banner &#xff08;五&#xff09;容器功能 (六)配置文件 二…

(九)枚举器和迭代器(1)

一、枚举器和可枚举类型 复习完了数组之后&#xff0c;由于数组遍历的这个行为&#xff0c;跟枚举器有很大的相关性&#xff0c;所以接下来继续要学习与枚举器相关的内容。 1、使用 foreach 语句 int[] arr1 { 10, 11, 12, 13 };foreach (int item in arr1)//枚举元素Consol…

尚硅谷大数据Flink1.17实战教程-笔记01【Flink概述、Flink快速上手】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷大数据Flink1.17实战教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据Flink1.17实战教程-笔记01【Flink概述、Flink快速上手】尚硅谷大数据Flink1.17实战教程-笔记02【Flink部署】尚硅谷…

【JVM 监控工具】性能诊断--JProfiler的使用

文章目录 背景一、Java 性能诊断工具简介二、简单命令行工具三、图形化综合诊断工具JVisualvmJProfiler 四、分布式应用性能诊断五、IDEA中设置JProfilerJProfiler是什么功能安装使用生成快照配置VM运行程序 背景 性能诊断是软件工程师在日常工作中需要经常面对和解决的问题&a…

公司新来的阿里p8,看了我做的APP和接口测试,甩给了我这份文档

移动应用App已经渗透到每个人的生活、娱乐、学习、工作当中&#xff0c;令人激动、兴奋且具有创造性的各种App犹如雨后春笋般交付到用户手中。各类智能终端也在快速发布&#xff0c;而开发者对于全球移动设备的质量和性能却掌握甚少&#xff0c;App与设备的兼容性问题常常导致用…