汇编语言--------王爽第三章

内存中字的存储

在CPU中我们用16位存储器来存储一个字,一个字大小是两个字节的大小,为16位。但是内存单元是字节单元,所以一个字要用两个内存单元来存储。这个字的低位字节单元放在低地址单元,而高位字节单元放在高地址单元。我们将其地址为N的字单元简称为N地址字单元 。

DS和[address]

CPU要读取一个内存单元的时候,必须要知道该内存单元的物理地址。我们一般用段地址和偏移地址来标记内存单元。8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。比如我们要访问10000H单元的内容,可以使用以下汇编指令。

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

8086CPU不允许直接将数据放入段寄存器中,所以我们需要个中转寄存器,通过将该寄存器中的内容传送到段寄存器中。第一条指令将1000H传入bx中,第二条指令将bx中的数据1000H传入ds段寄存器中。
mov 寄存器 [偏移地址],第二条指令给出了偏移地址,但是我们知道光靠偏移地址是无法定位到物理地址的,8086CPU通过读取ds中的数据作为默认段地址来使用,除非我们显示指定段地址。

mov、add、sub指令

mov add sub命令多不可以用来改变段寄存器中的值切记。

栈是一种特殊的结构模型,栈就相当于是一个盒子,我们多要向盒子里放东西多是从底部开始往下放,取东西时是从顶部开始取。栈就是类似这种结构,先进后出的结构,这种结构也被称为:LIFO(last in first out)。
8086提供了相关的指令以栈的方式访问内存空间。8086提供了最基本的两个命令是PUSH(入栈)POP(出栈)。push ax表示将寄存器ax的内容送入栈中,pop ax表示从栈中取出的数据送入ax中。8086CPU的入栈和出栈操作都是以字为单元进行的。下图描述了一段指令执行的过程。在这里插入图片描述
我们将一段内存当作栈使用,CPU执行push和pop指令将对这段空间按照栈的先进后出规则进行访问,但是问题在于CPU如何知道哪段内存空间是以栈的规则来处理的呢?
在8086CPU中SS和SP寄存器便是指定了哪段空间是栈。SS中存放的是栈顶空间的段地址,SP中存放的是偏移地址。SS:SP共同指定了栈顶元素。
push ax的执行,由以下两步完成。

  1. SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶元素前面的单元为新的栈顶。
  2. 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新的栈顶。

pop ax的执行,由以下两部完成。
1.将ss:sp指向的栈顶元素送入ax寄存器中。
2sp = sp +2.SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
我们在导论一下栈空间为空时SS:SP应该指向哪个内存单元。假如栈低最底部字单元为1000:E。SP应该为0010H。所以当栈为空时,SS:SP应该指向栈底部单元的下面的单元。

栈顶超界的问题

其实在CPU内存空间都是一样的,根本没有规定哪些内存空间为栈,只是我们人为规定哪些内存空间以栈的规则来访问。我们需要自己考虑栈顶超界的问题,自己想清楚写的指令是否会导致栈顶超界,自己规定哪些空间为栈空间,栈空间的大小是多少。
我们可以用pop和push命令修改段寄存器中的值。
debug模式中D命令 E命令 A命令 U命令多可以用段寄存器表示内存单元的段地址。比如 e ds:0折表示从物理地址为ds*16 + 0的存储单元开始修改值。

猜你喜欢

转载自blog.csdn.net/weixin_47617598/article/details/115014762