汇编 (3)寄存器 (内存访问)

一. 内存存储

1. 内存中字的存储

在0地址处开始存放20000(4E20H):
在这里插入图片描述

  • 0号单元是低地址单元,1号单元是高地址单元
  • 任何两个地址连续的内存单元,N号单元和 N+1号单元,可以看成一个地址为N 的字单元中的低位字节单元和高位字节单元

二. DS和[address]

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

  • AS 寄存器是存放CPU当前要读取指令的地址
  • DS 寄存器是存放要访问的数据的段地址

例1:读取10000H单元的内容:

  1. mov bx,1000H
  2. mov ds,bx
  3. mov al,[0]

上面三条指令将10000H(1000:0)中的数据读到al中(al是指ax的低寄存器)

注意:8086CPU不支持将数据直接送入段寄存器的操作,ds是一个段寄存器
错误:mov ds,1000H

例2:将al中的数据送入内存单元10000H:

  1. mov bx,1000H
  2. mov ds,bx
  3. mov [0],al

三. 字的传送

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

比如:
在这里插入图片描述
一个内存单元是8位的,执行完上面指令后,0号单元位存储的是cx中的低寄存器数据,1号单元位存储的是cx中的高寄存器数据

四. mov,add,sub

mov指令的几种形式:

mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 寄存器,段寄存器

add和sub指令同mov一样,都有两个操作对象
在这里插入图片描述

五. 数据段

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

例1:我们用123B0H~123B9H这段空间来存放数据:

段地址:123BH
长度:10字节

例2:将123B0H~123BAH的内存单元定义为数据段,我们现在要累加这个数据段中的前3个单元中的数据,代码如下:
在这里插入图片描述
例3:累加数据段中的前3个 字型数据
在这里插入图片描述

注意:一个字型数据占两个单元,所以偏移地址是0、2、4

六. 栈

栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于先进后出,后进先出
栈有两个基本的操作:入栈和出栈

  • 入栈:将一个新的元素放到栈顶
  • 出栈:从栈顶取出一个元素

8086CPU提供了两个最基本的入栈和出栈指令:

  • PUSH(入栈)例:push ax 将寄存器ax中的数据送入栈中
  • POP (出栈)例:pop ax 从栈顶取出数据送入ax

8086CPU的入栈和出栈操作都是以字为单位进行的
寄存器CS和IP中存放着当前指令的段地址和 偏移地址

8086CPU中,有两个寄存器:

  • 段寄存器SS  存放栈顶的段地址
  • 寄存器SP  存放栈顶的偏移地址

任意时刻,SS:SP指向栈顶元素
当栈为空的时,SP指向栈顶的下一个元素

6.1 push、pop指令

push和pop指令也是可以在寄存器和内存之间传送数据的

格式:

  • push 寄存器:将一个寄存器中的数据入栈 例:push ax

段寄存器:

  • pop寄存器:出栈,用一个寄存器接收出栈的数据 例:pop ax
  • push 段寄存器:将一个段寄存器中的数据入栈 例:push ds
  • pop段寄存器:出栈,用一个段寄存器接收出栈的数据 例:pop es

内存单元:

  • push内存单元:将一个内存单元处的字入栈(栈操作都是以字为单位)例:push [0]
  • pop 内存单元:出栈,用一个内存字单元接收出栈的数据 例:pop [2]

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

6.2 push 指令的执行过程
  1. SP=SP–2;
  2. 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶
    在这里插入图片描述
6.3 pop 指令的执行过程
  1. 将SS:SP指向的内存单元处的数据送入ax中;
  2. SP = SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶

在这里插入图片描述

  1. 出栈后,SS:SP指向新的栈顶 1000EH,pop操作前的栈顶元素,1000CH 处的2266H 依然存在 ,但是,它已不在栈中。
  2. 当再次执行push等入栈指令后,SS:SP移至1000CH,并在里面写入新的数据,它将被覆盖
6.4 栈顶超界的问题

SS和SP只记录了栈顶的地址,依靠SS和SP可以保证在入栈和出栈时找到栈顶,但是当栈满的时候再使用push指令入栈,栈空的时候再使用pop指令出栈,都将发生栈顶超界问题。

对于超界问题,cpu层面没有太好的预防措施,只能我们程序员在编写程序时要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界

6.5 栈段

对于8086PC机,在编程时,我们可以根据需要 ,将一组内存单元定义为一个段,可以将长度为 N(N ≤64K )的一组地址连续、起始地址为16的倍数的内存单元,当作栈来用,从而定义了一个栈段。

例:将10010H~1001FH 这段长度为 16 字节的内存空间当作栈来用,这样可以以栈的方式进行访问,这段空间就可以成为栈段,段地址为1000H,大小为16字节。然后将SS:SP指向我们定义的栈段,那么就可以支持push、pop 等栈操作指令访问。

猜你喜欢

转载自blog.csdn.net/haiyanghan/article/details/113801921
今日推荐