《汇编语言(第四版)》—王爽 第三章寄存器(内存访问) 详细笔记 ~后续章节笔记,课后检测,实验代码持续更新中

《汇编语言(第四版)》—王爽 第三章寄存器(内存访问) 详细笔记 ~后续章节笔记,课后检测,实验代码持续更新中

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

3.1、内存中字的存储

内存中从上到下依次为低位—>高位

任何两个地址连续的内存单元,N号单元和 N+1号单元,可以将它们看成两个内存单元,也可看成一个地址为N的字单元中的高位字节单元和低位字节单元。

在这里插入图片描述
例如:

在这里插入图片描述

解答:

在这里插入图片描述

3.2、DS和[address]

CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址

在8086中,内存地址是由段地址和偏移地址组成的

8086CPU中有一个DS寄存器,通常用来存放要存放的数据的段地址

可以使用mov指令将一个内存单元中的内容送入一个寄存器中。从哪一个内存单元送到哪一个寄存器中呢?在指令中必须指明。寄存器用寄存器名来指明,内存单元则需用内存单元的地址来指明。显然,此时mov指令的格式应该是: mov寄存器名,内存单元地址。

【…】表示的是一个内存单元,【…】中的表示内存单元中的偏移地址,在执行指令是8086会自动取ds中的数据为内存单元的段地址

8086CPU不支持将数据直接送入到段寄存器的操作,DS是一个段寄存器(硬件设计的问题),因此mov ds,1000H是非法的

数据–>通用寄存器–>段寄存器

将数据从寄存器送入到内存单元

mov bx,1000H
mov ds,bx
mov [0]al   #重点在于a'l[0]  和 [0]al的区别

3.3、字的传送

8086为16位的结构,有16根数据线,所以可以一次性传送16位的数据,也就是一次性传送一个字

例题:注意8086传送的是16位的字即两个字节,分为高8位和低8位

在这里插入图片描述
解答:

在这里插入图片描述

例题:注意16位,替换高位的内容,不要只替换低位而忽略高位

在这里插入图片描述

3.4、mov、add、sub指令

在这里插入图片描述

这样的写法是正确的,书本中出现了错误
mov 寄存器,段寄存器  表示的是将段寄存器中的数据给通用寄存器

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

add和sub是否能对段地址寄存器进行操作?(事实证明–不可以)

在这里插入图片描述

3.5、数据段

对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。

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

比如用123BOH123B9H这段内存空间来存放数据,我们就可以认为,123B0H123B9H 这段内存是一个数据段,它的段地址为123BH,长度为10个字节。

在这里插入图片描述

要选择低位进行操作,不然按照8086的16位数据AX寄存器会自动补全高位,AL是按照低位的8位进行的

在这里插入图片描述

这个问题问的是累加字型而非上一个问题中的单元

3.1~3.5 小结

  • 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,,高位字节存放在高地址单元中。
  • 用mov 指令访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中
  • [address]表示一个偏移地址为address的内存单元。
  • 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
  • mov、add、sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。
  • 可以根据自己的推测,在Debug 中实验指令的新格式。

检测点例题说明

在这里插入图片描述
重点:CS和IP是用了来寻找指令的

DC以及[偏移量]是用来寻找数据的

3.6、栈

栈是一种具有特殊的访问方式的存储空间。它的特殊性在于,最后进入这个空间的数据最先出去

栈的两个基本操作:入栈和出栈

栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出

栈的操作原则:LIFO(后进先出)

3.7、CPU提供的栈机制

8086CPU提供相关的指令来以栈的方式访问内存空间,因此基于8086CPU编程时,可以将一段内存当作栈来使用

8086提供的入栈出栈的指令(最基本):push(入栈) pop(出栈)

push ax:将寄存器ax中的数据送入到栈中
pop  ax:从栈顶取出数据送入到ax中
pop 指令就是取栈顶的数据

8086CPU的入栈和出栈都是以字为单位进行的

一段指令的执行过程,注意内存空间从哪里开始存储,是从这段空间中相对较大处开始的,符合栈先进后出的规则

在这里插入图片描述
存在两个问题:

  • CPU如何知道一段内存空间被当作栈来使用?
    • 8086CPU中,有两个寄存器
      • 段寄存器SS 存放栈顶的段地址
      • 寄存器SP 存放栈顶的偏移地址
    • 任何时候,SS:SP指向栈顶元素
  • 执行push和pop的时候,如何知道哪个单元是栈的顶部?
    • 执行push时
      • SP = SP - 2
      • 将ax中的内容送入到SS:SP指向的内存单元
      • SS:SP此时为新的栈顶
    • 执行pop时
      • 将SS:SP指向的内存单元中的内容送入到ax
      • SP = SP + 2
      • SS:SP此时为新的栈顶

当栈空时,SP指向的时最高地址的下一个单元(任何时刻,SS:SP指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素 ,所以SS:SP只能指向栈的最底部单元的下面一个单元)

栈最底部 字 单元的地址为1000:000E,则栈为空时,SP为000E + 2 ------->0010H

在我们执行pop命令时,数值复制到寄存器中,在栈中该数据还是存在的,等待下一次执行push时将这个数值覆盖掉了

利用编译语言来理解栈:

  • 在我们调用函数时,会利用部分变量的数据,但是不能改变这些原有的变量的数值,因此利用到栈,先将数据全部读取到栈中,然后函数进行运算,做完一系列操作之后,再将栈中的数据取出,来还原变量
  • 局部变量只在局部起作用,则局部变量也是放在栈中

3.8、栈顶超界的问题

SS和SP只记录了栈顶的地址,依靠SS和SP可以保证在入栈和出栈时找到栈顶

栈顶超界问题:在栈满时继续使用push命令,在栈空时继续使用pop命令

栈顶超界时很危险的

在这里插入图片描述
在这里插入图片描述
8086CPU不保证对栈的操作不会越界,8086CPU只知道栈顶在何处,而不知道安排的栈的空间有多大

我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。

3.9、push和pop指令

push和pop指令时能够在寄存器和内存之间传送数据的

栈与内存:栈空间当然也是内存空间的一部分,他只是一段可以以一种特殊的方式进行访问的内存空间

push 寄存器:将寄存器中的数据放入栈中
push 段寄存器:将一个段寄存器中的数据入栈
push 内存单元:将一个内存单元处的字入栈(栈的操作都是以字为单位)
pop  寄存器:将栈中的数据放入寄存其中
pop  段寄存器:出栈,用一个段寄存器接受出栈的数据 
pop  内存空间:出栈,用一个内存字单元接受出栈的数据 pop[2]
指令在执行时,CPU要知道内存的地址,可以在push、pop指令中给出内存单元的偏移地址,段地址在指令指向时,CPU从ds中取得

push、pop实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和 pop 指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。同时,push和 pop指令还要改变SP中的内容

例题分析:(push和pop指令,还要改变SP的内容)

在这里插入图片描述

补充之后代码如下:

在这里插入图片描述

在检测时自我出现的问题:(需要格外注意的地方)

将SP的值置为了1,问题分析,对于栈的 + 2 以及 - 2 的方式还不是很熟悉,以及对于SS:SP永远指向栈顶理解不透彻

对于栈的知识注意的有:

  • pop和push等栈操作指令,修改的只有SP的值,也就是说栈顶的最大变化范围为0~FFFFH(因为是16位)

3.10、栈段

对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。

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

比如,我们将10010H~1001FH 这段长度为16字节的内存空间当作栈来用,以栈的方式进行访问。这段空间就可以称为一个栈段,段地址为1001H,大小为16字节。

将一段内存当作栈段,仅仅是我们在编程时的一种安排,CPU不会这样安排

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CYS.burst

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值