汇编语言之寄存器(内存访问)

1、内存中字的存储

2、ds和【address】

CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086CPU中,内存地址由段地址和偏移地址组成,

其中,段地址存放在段寄存器DS中,DS称作数据段寄存器。

如果我们要将内存地址为14A70的内存单元中的数据送入AL中,可以用如下的程序段进行:

Mov bx,1000H    ;把段地址1000H送入bx中。

mov ds,bx        ;把bx中的数值送入ds中。

Mov al,[4a70]     ;把段地址为1000H,偏移地址位4a70H的内存单元中的数据送入al中。

[address]表示一个内存单元,内存单元中的address表示偏移地址,它的中文翻译就是地址的意思。

内存单元[address],我们可以知道它的地址是多少,但它的数值是多少,我们并不知道。

3、mov指令

传送指令mov可以完成以下4种传送:

1:将数据直接送入寄存器。    如:mov ax,1230H。

2:将一个寄存器中的数据送入另一个寄存器。    如:mov ax,bx

3:将一个内存单元中的数据送入一个寄存器。    如:mov ax,[27b0]

4:将一个寄存器中的数据送入内存单元中。    如:mov [607c],bx

注意:不能直接用数据送给段寄存器,如:mov ds,1230H 是错误的,必须要用一个寄存器来进行中转。比如:

Mov bx,1230H

Mov ds,bx

这样就行了。为什么8086CPU不支持将数据直接送入段寄存器呢?这属于8086CPU硬件设计的问题,我们只要知道这一

点就行了。

4、add和sub指令

Mov指令有两个操作对象,add和sub同样有两个操作对象。

Add为加法指令,格式:add 操作对象1,操作对象2。功能:两数相加,并把结果保存到操作对象1中。

Add有以下几种形式:

Add 寄存器,数据    如:add ax, 8

Add 寄存器,寄存器    如:add ax, bx

Add 寄存器,内存单元    如:add ax, [27a0]

Add 内存单元,寄存器    如:add [46e9], bx

 

Sub为减法指令,格式:sub 操作对象1,操作对象2。功能:两数相减,即从操作对象1减去操作对象2,其结果保存到

操作对象1中。

Sub 也有以下几种形式:

Sub 寄存器,数据    如:sub ax, 9

Sub 寄存器,寄存器    如:sub ax, bx

Sub 寄存器,内存单元    如:sub ax, [b027]

Sub 内存单元,寄存器    如:sub [8601], bx

5、数据段

前面讲过(参见2.7节),对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。我们可以将一组长度

为N(N≤64KB)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。

比如:用123B0H~123B9H这段内存空间来存放数据,我们就可以认为123B0H~123B9H这段内存是一个数据段,长度

为10个字节。

如何访问数据段中的数据呢?首先用DS存放数据段的段地址,然后用相关的指令访问数据段中的内存单元。

比如,将123B0H~123B9H的内存单元定义为数据段,现在要累加这个数据段中的前3个单元中的数据,代码如下:

Mov ax, 123BH

Mov ds, ax    ;将123BH送入ds中,作为数据段的段地址。

Mov al, 0      ;用al存放累加结果,先把al中的数据清零。

Add al, [0]     ;将数据段第一个单元(偏移地址为0)中的数值加到al中。

Add al, [1]     ;将数据段第二个单元(偏移地址为1)中的数据加到al中。

Add al, [2]     ;将数据段第三个单元(偏移地址为2)中的数据加到al中。

 

在1.5节中,我们说过,在内存中指令和数据没有任何区别,都是二进制信息,CPU在工作的时候,把有的信息看作指令,

把有的信息看作数据,那么CPU在什么时候把它看作指令?在什么时候把它看作数据呢?在2.5节中我们回答了第一个问题,现

在可以回答第二个问题了。

答:只要把这一段内存单元的段地址放到DS中,在用mov、add、sub等访问内存单元的指令时,CPU就会将这些内存单

元看作数据来访问。

6、栈

栈是一种具有特殊的访问方式的存储空间,它的特殊性就在于:最后进入这个空间的数据最先出去。可以用一个盒子和3本书

来描述栈的这种操作方式。

入栈:把A放入栈中,再把B放入栈中,然后再把C放入栈中。就形成了A、B、C

出栈:先出栈顶C,然后是B,然后A,

特点:先进后出

入栈和出栈。入栈就是将一个新的元素放到栈顶,出栈就是从栈

顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时又最先被从栈中取出,栈的这种操作规则被称为LIFO(last in first out,

后进先出)

 

7、cpu提供的栈机制 

现今的CPU中都有栈的设计。8086CPU提供的入栈和出栈指令,最基本的两个是push(入栈)和pop(出栈)。比如:

Push ax 表示将寄存器ax中的数据送入栈中,pop ax 表示从栈顶取出数据送入ax。8086CPU的入栈和出栈操作都是以字为

单位进行的。

下面两张图描述了push和pop指令的执行过程。

上面两张图指令的执行过程,写成代码如下:

Mov ax, 123H

Push ax

Mov bx, 2266H

Push bx

Mov cx, 1122H

Push cx

Pop ax

Pop bx

Pop cx

注意:字型数据用两个内存单元存放,高地址单元存放高8位,低地址单元存放低8位。

看了上面两张图后,现在提出两个问题。问题1:我们将10000H~1000FH这段内存当作栈来使用,CPU是如何知道这段空

间是栈?关于这个问题将在3.10节解答。

问题2:push ax等入栈指令执行时,要将寄存器中的数据放入当前栈顶单元的上方,成为新的栈顶元素;pop ax等指令执

行时,要从栈顶单元取出数据送入寄存器中。显然,push、pop在执行的时候,CPU必须要知道哪个单元是栈顶单元,可是,如

何知道?

答:8086CPU中,有两个寄存器,堆栈段寄存器SS,堆栈指针寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在

SP中,任意时刻,SS:SP指向栈顶元素,push和pop指令在执行时,CPU从SS和SP中得到栈顶单元的地址。

现在,我们可以完整地描述push和pop指令的功能了,例如:push ax。push ax的执行,由以下两步完成:

1. SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶。

2. 将ax中的数据送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。

下图描述了push ax的执行过程。

将10000H~1000FH这段空间当作栈段,SS=1000H,栈空间大小为16字节,栈最底部的字单元地址为1000:000E,任

意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=000EH,栈为空,就相当于栈中唯一的元素出栈后,

SP=SP+2,原来为000EH,加2后SP=0010H,所以,当栈为空的时候,SS=1000H,SP=0010H。

换一个角度看,任意时刻,SS:SP指向栈顶元素,当栈为空的时候栈中没有元素,也就不存在栈顶元素,所以SS:SP只能指

向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2,栈最底部字单元的地址为1000:000E,

所以,栈空时,SP=0010H。

接下来,我们描述pop指令的功能,例如:pop ax。Pop ax的执行过程和push ax刚好相反,由以下两步完成:

1. 将SS:SP指向的内存单元处的数据送入ax中。

2. SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

下图描述了pop ax的执行过程。

注意:上图中,出栈后,SS:SP指向新的栈顶1000EH,pop操作前的栈顶元素,1000CH处的数据2266H依然存在,但

是,它已不在栈中,当再次执行push等入栈指令后,SS:SP移至1000CH,并在里面写入新的数据,将它覆盖。

8、push指令 pop指令

Push和pop指令的格式有如下两种形式:

第一种形式:push 寄存器    ;将一个寄存器中的数据入栈。

            Pop 寄存器    ;出栈,用一个寄存器接收出栈的数据。

这一种形式,它们可以在栈和寄存器之间传送数据。

注意:上面的寄存器可以是段寄存器,比如,可以是:push ds、pop ds。

第二种形式:push 内存单元    ;将一个内存单元中的字型数据入栈(注意,栈操作都是以字为单位)。

            Pop 内存单元    ;出栈,用一个内存字单元接收出栈的数据。

比如:mov ax, 1000H

      Mov ds, ax    ;将内存单元的段地址放在DS中。

      Push [2a38]    ;将内存单元[2a38]中的字型数据入栈。

      Pop [2a3a]    ;出栈,出栈的数据送入内存单元[2a3a]。

这一种形式,它们可以在栈和内存单元之间传送数据。

指令执行时,CPU要知道内存单元的地址,可以在push、pop指令中给出内存单元的偏移地址,段地址在指令执行时,CPU

从DS中取得。

Push和pop实质上是一种内存传送指令,与mov指令不同的是,push和pop指令访问的栈空间的地址不是在指令中给出

的,而是由SS:SP指出的。同时,push和pop指令还要改变SP中数值。Mov指令只需一步操作,就是传送,而执行push、

Pop指令需要两步操作,执行push时,先改变SP,后向SS:SP处传送;执行pop时,先读取SS:SP处的数据,后改变SP。

9 、 栈段

前面讲过(参见2.7节),对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。我们可以将长度为N

(N≤64KB)的一组地址连续、起始地址为16的倍数的内存单元,当作栈空间来用,从而定义了一个栈段。

比如,我们将10010H~1001FH这段内存空间当作栈来用,以栈的方式进行访问,这段空间就可以认为是一个栈段,大小为

16个字节。

如何使得如push、pop等栈操作指令访问我们定义的栈段呢?那就是要将SS:SP指向我们定义的栈段。

现在我们来回答3.8节中的第一个问题。答:只要这段内存单元被SS:SP指向,那么,CPU就会把这段空间当作栈来使用。



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

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

相关文章

用sort()方法随机打乱数组

2019独角兽企业重金招聘Python工程师标准>>> 我们先看一下随机数组排序的示例,再来研究其中的原理。 随机数组排序示例 var numbers [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; numbers numbers.sort(function(…

Linux下部署Kubernetes+Kubesphere(一)Kubernetes基础

1.服务器规划为配置Kubesphere高可用集群,需要三台或三台以上机器作为Master节点,每台机器既可以作为Master也可以作为Worker节点。其中Master节点数量建议为单数。该示例中采用三台服务器,即作为Master节点也作为Worker节点,配置…

触发器及其应用实验报告总结_调机技巧总结: 先快后慢射胶法及其应用

戳我进入社区:注塑和模具人的网上家园先快后慢,也即先用一级快速射胶,射到某个设定的位置时,再起二级慢速射胶。这个二级起级点一般是设在射胶充型的后期,也即接近充型结束的位置。使用一级快速射胶,可以保…

使用 dotnet-monitor 在 Kubernetes 中收集 .NET metrics

使用 dotnet-monitor 在 Kubernetes 中收集 .NET metricsIntrodotnet-monitor 是微软推出的一个帮助我们诊断和监控 .NET 应用程序的工具,在 Kubernetes 中我们可以让 dotnet-monitor 作为 sidecar 运行,无侵入地监控 .NET 应用,今天我们就来…

arcgis 分区 属性值_ArcGIS制图之Maplex自动点抽稀

制图工作中,大量密集点显示是最常遇到的问题。其特点是分布可能不均匀、数据点比较密集,容易造成空间上的重叠,影响制图美观。那么,如果美观而详细的显示制图呢?主要原理Maplex中对标注有很好的显示控制,一…

学术造假导致导师自杀,后将这段学术丑闻经历出书贩卖,一年收入上百万......

全世界只有3.14 % 的人关注了爆炸吧知识本文转自募格学术2020年2月11日,小保方晴子又被撤回了一篇研究论文。Tissue Engineering Part A撤稿给出的原因是:通过哈佛医学院正式调查后,无法确实其实验结果的准确性,尽管作者本人坚持已…

汇编语言之数据处理的2个基本问题

1、bx、si、di和bp Bx、si和di这3个寄存器我们已经学过了,现在进行一下总结,并学一下bp。 1:在8086CPU中,只有这4个寄存器可以用在[…]中来进行内存单元的寻址。比如,下面的指令都是正确 的…

nvm用标准sata ahci码_能者多劳!让NVMe固态硬盘做系统盘的同时,加速SATA数据盘...

不知不觉当中,固态硬盘已经取代机械硬盘成为主流。越来越多的玩家已经淘汰机械盘,使用NVMeSATA的固态硬盘高低搭配。既然是高低搭配,就一定会有性能差距,是否能从NVMe固态硬盘中划分出一小部分空间来给SATA固态硬盘加速&#xff0…

天了噜!定义static字段还有顺序要求?

前言前段时间,发现一个bug,代码结构类似下面的示例。你能说出这段代码的正确返回结果吗?class Program {private static int a1 a2;private static int a2 Init();private static int Init(){return 123;}static void Main(string[] args){…

汇编语言之转移指令和原理

1、引言 可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括地讲,转移指令就是可以控制CPU执行内存 中某处代码的指令。 8086CPU的转移行为有以下几类: 1. 同时修改CS和IP时,称为段间转移&#…

【高德地图开发2】---配置工程

1.从网站下载开发包并解压。 3D地图包解压后得到:3D地图显示包“Android_Map_2.x.x.jar ”和文件夹“ armeabi ”(以 V2.2.0为例,含 - libamapv302.so 和 libmapv302ex.so 文件)。2D地图包解压后得到:2D地图显示包“An…

antd option宽度自适应_建议收藏:Axure手机自适应教程

hello,我又来啦,今天和大家分享用axure怎么做自适应,也就是说,我们做app端的作品时,怎么在不同的手机尺寸,显示最佳的样式。那么这期的话,我会以一个游戏的案例来展开,所以比较好玩。…

安装pip

2019独角兽企业重金招聘Python工程师标准>>> linux系统安装pip: 1.下载get-pip.py wget https://bootstrap.pypa.io/get-pip.py 2.安装pip python get-pip.py windows系统安装pip,这里使用easy_install: 1.首先在命令行切换到easy_install.exe所在的Scri…

所以,路遥工具箱到底是什么东西?

笔者的软件开发生涯是从 2008 年开始的,彼时还是 2G 时代。站长之家是笔者当时经常访问的网站,站长工具也成为当时探索网络世界时的入门工具。软件开发这些年也是浑浑噩噩的度过,鲜有建树。2020 年之前也写了一些小工具用于解决一些注入字符串…

刷1000遍奥数题,不如学会这几道逻辑题,让孩子秒懂数学,学习早开窍!

▲ 点击查看前阵子发现一个英国BBC制作的纪录片,叫《逻辑的乐趣》(The Joy Of Logic),介绍了逻辑的概念,逻辑的发展史,及其在现实生活中的应用和价值。讲解非常有意思,深入浅出,风趣…

oracle技术之顺序文件上的索引(一)

顺序文件上的索引(一)研究索引结构,我们首先来考虑最简单的一种:由一个称为数据文件的排序文件得到另一个称为索引文件的文件,而这个索引文件由键-指针对组成。在索引文件中查找键K通过指针指向数据文件中查找键为K的记…

汇编语言之标志寄存器

1、标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作 用: 1. 用来存储相关指令的某些执行结果。 2. 用来为CPU执行相关指令提供行…

web网页的表单排版利器--960css

表单排版样式 960css 前言 一般web网页的表单排版,大家都习惯用table排版,自己需要根据实际需要去定义TR和TD,很多时候对于TD的高宽度、是否合并行,合并列,都要去做一些处理,这些都是比较繁琐的工作。找到一…