首页 > 系统相关 >3.1 内存中自动存储—3.4 mov、add、sub 指令

3.1 内存中自动存储—3.4 mov、add、sub 指令

时间:2024-05-28 16:59:39浏览次数:12  
标签:sub mov MOV 3.4 指令 内存 寄存器 单元

 

第3章 寄存器(内存访问)

在第2章中,我们主要从CPU如何执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、相关的寄存器以及一些指令。读者应在通过了前一章所有的检测点,并完成了实验任务之后,再开始学习当前的课程。本章中,我们将从访问内存的角度继续学习几个寄存器。

3.1 内存中字的存储

在CPU中,用16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节。在内存中存储时,由于内存单元是字节单元(一个单元存放一个字节),则一个字需要用两个地址连续的内存单元来存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。例如:

地址数据
020H
14EH
212H
300H
420000

这种情况如图3.1所示。

图3.1 内存中字的存储

在图3.1中,我们用0、1两个内存单元存放数据20000(4E20H)。0、1两个内存单元用来存储一个字,这两个单元可以看作一个起始地址为0的字单元(存放一个字的内存单元,由0、1两个字节单元组成)。对于这个字单元来说,0号单元是低地址单元,1号单元是高地址单元,因此字型数据4E20H的低位字节存放在0号单元中,高位字节存放在1号单元中。同理,将2、3号单元看作一个字单元,它的起始地址为2。在这个字单元中存放数据0012H,则在2号单元中存放低位字节12H,在3号单元中存放高位字节00H。

我们提出字单元的概念:字单元,即存放一个字型数据(16位的内存单元,由两个地址连续的内存单元组成)。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。在以后的课程中,我们将起始地址为N的字单元简称为N地址字单元。例如,一个字单元由2、3两个内存单元组成,则这个字单元的起始地址为2,我们可以说这是2地址字单元。

问题3.1

对于图3.1:

  1. 0地址单元中存放的字节型数据是多少?
  2. 0地址字单元中存放的字型数据是多少?
解答:
  1. 0地址单元中存放的字节型数据是20H。
  2. 0地址字单元中存放的字型数据是4E20H。

通过对内存中数据存储方式的理解,我们可以更好地掌握8086CPU的寄存器和内存访问方式。在下一节中,我们将继续探讨更多关于寄存器和内存访问的内容。

 

 

3.2 DS和[address]

CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中内存地址由段地址和偏移地址组成。8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。比如我们要读取10000H单元的内容,可以用如下的程序段进行:


assembly

复制代码

mov bx, 1000H mov ds, bx mov al, [0]

上面的3条指令将10000H(01000:0)中的数据读到AL中。

指令含义说明

mov al, [0]:前面我们使用MOV指令,可以完成两种传送:①将数据直接送入寄存器;②将一个寄存器中的内容送入另一个寄存器。也可以使用MOV指令将一个内存单元中的内容送入一个寄存器中。从哪一个内存单元送到哪一个寄存器中呢?在指令中必须指明。寄存器用寄存器名来指明,内存单元则需用内存单元的地址来指明。显然,此时MOV指令的格式应该是:MOV寄存器名,内存单元地址。

[--]表示一个内存单元,[--]中的0表示内存单元的偏移地址。我们知道,只有偏移地址是不能定位一个内存单元的,那么内存单元的段地址是多少呢?指令执行时,8086CPU自动取DS中的数据为内存单元的段地址。

再来看一下,如何用MOV指令从10000H中读取数据。10000H用段地址和偏移地址表示为1000:0,我们先将段地址1000H放入DS,然后用MOV AL, [0]完成传送。MOV指令中的[说明操作对象是一个内存单元,[0]中的0说明这个内存单元的偏移地址是0,它的段地址默认放在DS中,指令执行时,8086CPU会自动从DS中取出段地址。

mov bx, 1000H
mov ds, bx
mov al, [0]

若要用MOV AL, [0]完成数据从10000H单元到AL的传送,这条指令执行时,DS中的内容应为段地址1000H,所以在这条指令之前应该将1000H送入DS。

如何把一个数据送入寄存器呢?我们以前用类似“MOV AX, 1”这样的指令来完成,从理论上讲,我们可以用相似的方式:MOV DS, 1000H,来将1000H送入DS。可是,现实并非如此,8086CPU不支持将数据直接送入段寄存器的操作,DS是一个段寄存器,所以MOV DS, 1000H这条指令是非法的。那么如何将1000H送入DS呢?只好用一个寄存器来进行中转,即先将1000H送入一个一般的寄存器,如BX,再将BX中的内容送入DS。

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

问题3.2

写几条指令,将AL中的数据送入内存单元10000H中,思考后看分析。

分析

怎样将数据从寄存器送入内存单元?从内存单元到寄存器的格式是:“MOV寄存器名,内存单元地址”,从寄存器到内存单元则是:“MOV内存单元地址,寄存器名”。10000H可表示为1000:0,用DS存放段地址1000H,偏移地址是0,则MOV [0], AL可完成从AL到10000H的数据传送。完整的几条指令是:

mov bx, 1000H
mov ds, bx

 

3.3 字的传送

前面我们用MOV指令在寄存器和内存之间进行字节型数据的传送。因为8086CPU是16位结构,有16根数据线,所以可以一次性传送16位的数据,也就是说可以一次性传送一个字。只要在MOV指令中给出16位的寄存器就可以进行16位数据的传送了。比如:

mov bx, 1000H
mov ds, bx
mov ax, [0] ; 1000:0处的字型数据送入AX
mov [0], ax ; AX中的16位数据送到1000:0处

问题3.3

内存中的情况如图3.2所示,写出下面的指令执行后寄存器AX, BX, ES中的值。

mov ax, 1000H
mov ds, ax
mov ax, [0]
mov bx, [2]
mov es, [1]
add bx, [1]

内存中的初始数据如下:

地址数据
10000H23H
10001H11H
10002H22H
10003H66H

分析

进行单步跟踪,看一下每条指令执行后相关寄存器中的值,见表3.1。

表3.1 指令执行与寄存器中的内容
指令执行后相关寄存器中的内容说明
mov ax, 1000HAX = 1000H
mov ds, axDS = 1000H前两条指令的目的是将DS设为1000H
mov ax, [0]AX = 1123H1000:0处存放的字型数据送入AX。高8位11H,低8位23H
mov bx, [2]BX = 6622H1000:2处存放的字型数据送入BX。高8位66H,低8位22H
mov es, [1]ES = 2211H1000:1处存放的字型数据送入ES。高8位22H,低8位11H
add bx, [1]BX = 88ABHBX加上1000:1处存放的字型数据

执行后的寄存器值:

  • AX = 1123H
  • BX = 88ABH
  • ES = 2211H

问题3.4

内存中的情况如图3.3所示,写出下面的指令执行后内存中的值。

mov ax, 1000H
mov ds, ax
mov ax, 11316
mov [0], ax
mov bx, [0]
sub bx, [2]
mov [2], bx

内存中的初始数据如下:

地址数据
10000H23H
10001H11H
10002H22H
10003H1H

分析

进行单步跟踪,看一下每条指令执行后相关寄存器或内存单元中的值,见表3.2。

表3.2 指令执行与寄存器中的内容
指令执行后相关寄存器和内存单元中的内容说明
mov ax, 1000HAX = 1000H
mov ds, axDS = 1000H前两条指令的目的是将DS设为1000H
mov ax, 11316AX = 2C34HAX中的数据为2C34H
mov [0], ax[1000:0] = 34H, [1000:1] = 2CHAX中的数据送到1000:0处,高8位送入1000:1,低8位送入1000:0
mov bx, [0]BX = 2C34H1000:0处存放的字型数据送入BX
sub bx, [2]BX = 1B12HBX减去1000:2处的字型数据22H
mov [2], bx[1000:2] = 12H, [1000:3] = 1BHBX中的数据送到1000:2处,高8位送入1000:3,低8位送入1000:2

执行后的内存值:

地址数据
10000H34H
10001H2CH
10002H12H
10003H1BH

 

3.4 MOV、ADD、SUB指令

前面我们用到了MOV、ADD、SUB指令,它们都带有两个操作对象。到现在为止,我们知道,MOV指令可以有以下几种形式:

  • MOV 寄存器, 数据 比如:MOV AX, 8
  • MOV 寄存器, 寄存器 比如:MOV AX, BX
  • MOV 寄存器, 内存单元 比如:MOV AX, [0]
  • MOV 内存单元, 寄存器 比如:MOV [0], AX
  • MOV 段寄存器, 寄存器 比如:MOV DS, AX

图3.5 测试MOV [0], CS指令

在图3.5中,当CS

指向0B39:0105的时候,Debug显示当前的指令MOV [0000], CS。因为这是一条访问内存的指令,Debug还显示出指令要访问的内存单元中的内容。由于指令中的CS是一个16位寄存器,所以要访问(写入)的内存单元是一个字单元,它的偏移地址为0,段地址在DS中,Debug在屏幕右边显示出“DS:0000-0000”,我们可以知道这个字单元中的内容为0。

MOV [0000], CS执行后,CS中的数据(0B39H)被写入1000:0处,1000:1单元存放0BH,1000:0单元存放39H。

最后,用D命令从1000:0开始查看指令执行后内存中的情况,注意1000:0、1000:1两个单元的内容。

mov ax, 1000H
mov ds, ax
mov [0], cs

在Debug中进行试验,如图3.5所示。

MOV 段寄存器, 内存单元

MOV段寄存器可以从内存单元读取数据,比如我们可以用10000H处存放的字型数据设置DS(即将10000H处存放的字型数据送入DS),指令如下:

mov ax, 1000H
mov ds, ax
mov ds, [0]

可以自行在Debug中进行试验。

ADD和SUB指令

ADD和SUB指令与MOV一样,也有两个操作对象。它们也可以有以下几种形式:

  • ADD 寄存器, 数据 比如:ADD AX, 8
  • ADD 寄存器, 寄存器 比如:ADD AX, BX
  • ADD 寄存器, 内存单元 比如:ADD AX, [0]
  • ADD 内存单元, 寄存器 比如:ADD [0], AX
  • SUB 寄存器, 数据 比如:SUB AX, 9
  • SUB 寄存器, 寄存器 比如:SUB AX, BX
  • SUB 寄存器, 内存单元 比如:SUB AX, [0]
  • SUB 内存单元, 寄存器 比如:SUB [0], AX

它们可以对段寄存器进行操作吗?比如“ADD DS, AX”。请自行在Debug中试验。

以上内容总结了MOV、ADD、SUB指令的各种形式及其在内存和寄存器之间的数据传送操作。这些指令在8086汇编语言编程中具有广泛的应用,是理解和编写汇编程序的基础。

 

 

 

 

 

标签:sub,mov,MOV,3.4,指令,内存,寄存器,单元
From: https://blog.csdn.net/tang7mj/article/details/139271555

相关文章

  • Vue3.4+版本中的 defineModel 宏的用法示例
    关于defineModel,Vue官方给出了较为详细的解释,具体请看文档说明下面是整理出的一个简易示例:子元素代码://Comp.vue<scriptsetup>constmsg=defineModel('msg',{type:String,default:''});constscore=defineModel('score',{type:Number,default:0})......
  • LLCC68低功耗Sub-GHz LoRa射频收发器LLCC68IMLTRT
    目录·LLCC68简介·主要特性·射频开关参考原理图·应用领域LLCC68简介LLCC68是一款Sub-GHzLoRa射频收发器,适用于中距离室内以及室内到室外的无线应用。支持SPI接口。与SX1262的引脚兼容,专为延长电池寿命而设计,有效接收电流消耗低至4.2mA。SX1261、SX1262、SX1268和LLCC68是专......
  • move base全解
    0.简介之前我们专门有一节讲到了《move_base源码学习》。主要介绍了MoveBase基类中函数的大概意思以及调用的方式。move_base是ROS下关于机器人路径规划的中心枢纽。它通过订阅激光雷达、map地图、amcl的定位等数据,然后规划出全局和局部路径,再将路径转化为机器人的速度信......
  • C++程序分享--常见算法/编程面试题:(百度笔试题)用 C 语言实现函数 void * memmove
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;有意找工作的同学,请参考博主的原创:《面试官心得--面试前应该如何准备》,《面试官心得--面试时如何进行自我介绍》, 《做好面试准备,迎接2024金三银四》。【图解《程序员面试常见的......
  • [转帖]Moving the JDK to a Two Year LTS Cadence
    https://blogs.oracle.com/java/post/moving-the-jdk-to-a-two-year-lts-cadence?spm=a2c6h.12873639.article-detail.10.27b5e6ceactmHU ExecutiveSummary:OracleproposestoshiftthecadenceofJDKLTSreleasesfromeverythreeyearstoeverytwoyears. ......
  • 《软件方法(下)》8.3.4.3 关于“整体-部分”结构
    DDD领域驱动设计批评文集做强化自测题获得“软件方法建模师”称号《软件方法》各章合集8.3建模步骤C-2识别类的关系8.3.4识别关联关系8.3.4.2关联的进一步细分是否进一步细分各种关联,各种面向对象方法学观点不同。有的认为关联就是关联,不用再细分,有的则认为需要进一......
  • ABB、Epson、Mitsubishi、Comau、Kuka、Kawasaki、QKM、YASKAWA、Nachi、Fanuc、Denso
    机器人编程助手:高效编程的实用工具机器人编程助手是一款旨在提高工业机器人编程效率的软件。支持ABB、Epson、Mitsubishi、Comau、Kuka、Kawasaki、QKM、YASKAWA、Nachi、Fanuc、Denso等多个品牌。软件内置参考手册、接线图和程序模板,帮助用户快速上手和高效完成编程任务......
  • 如何让ALG、FPGA、EMU、SOC、SubIp实现驱动复用
       摘要        在芯片验证场景中,我们通常涉及到算法team、fpga测试team、EMUteam、SOC验证和Subip验证如何对芯片的完备性测试的探讨。由于各个team都是相互独立的,很多flow都是独立开发出来,对于交互的文件也是五花八门,这些文件各team协助起来很不方便,如何打通......
  • 将 MOV 转换为 MP4 的 10 个最佳工具
    在当今的数字时代,内容创作和消费正处于巅峰,对多功能和兼容媒体格式的需求从未如此之高。在众多可用的视频格式中,MOV和MP4因其在各种设备和平台中的广泛使用而脱颖而出。然而,将MOV文件转换为更通用兼容的MP4格式的需求已成为用户寻求确保其视频可在所有设备和平台上播放......
  • LeetCode 283. Move Zeroes All In One
    LeetCode283.MoveZeroesAllInOnearrayin-placeswap/数组就地交换算法errorsfunctionmoveZeroes(nums:number[]):void{//in-place就地交换letindex=0;//letflag=false;for(leti=0;i<nums.length;i++){if(nums[i]===0){......