继第二章学习过从CPU如何让执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、相关的寄存器以及一些指令之后,我们提出字单元的概念,字单元是用来存放一个16位字型数据的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,也可看成一个地址为N的字单元中的高位字节单元和低位字节单元。CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中,内存地址由段地址和偏移地址组成。8086CPU 中有一个DS寄存器,通常用来存放要访问数据的段地址。使用mov指令,可完成将数据直接送入寄存器以及将一个寄存器中的内容送入另一个寄存器。也可以使用mov指令将一个内存单元中的内容送入一个寄存器中。从哪一个内存单元送到哪一个寄存器中在指令中必须指明。
寄存器用寄存器名来指明,内存单元则需用内存单元的地址来指明。对于8086PC机,在编程时,可以根据需要,将一组内存单兀定义为一个段。我们可以将一组长度为N(N≤64KB)、地址连续、起始地址为16 的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。比如用123B0H~123B9H这段内存空间来存放数据,我们就可以认为,123B0H~123B9H 这段内存是一个数据段,它的段地址为123BH,长度为10个字节。如果要访问数据段中的数据,则要将段内存当作数据段, 是我们在编程时的一种安排,可以在具体操作的时候,用ds存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元。
对于栈的研究,仅限于栈是一种具有特殊的访问方式的储存空间。它的特殊性就在于,最后进入这个空间的数据,最先出去。当栈满的时候再使用push指令入栈,或栈空的时候再使用pop指令出栈,都将发生栈顶超界问题。栈顶超界是危险的,因为我们既然将一段空间安排为栈,那么在栈空间之外的空间里很可能存放了具有其他用途的数据、代码等,这些数据、代码可能是我们自己程序中的,也可能是别的程序中的,毕竟一个计算机系统中并不是只有我们自己的程序在运行。但是由于我们在入栈出栈时的不小心,而将这些数据、代码意外地改写,将会引发一连 串的错误。
8086CPU不保证我们对栈的操作不会超界。这也就是说,8086CPU由SS:SP指示只知道栈顶在何处,而不知道我们安排的栈空间有多大。这点就好像CPU由CS:IP指示只知道当前要执行的指令在何处,而不知道要执行的指令有多少。从这两点上我们可以看出8086CPU的工作机理,它只考虑当前的情况:当前的栈顶在何处、当前要执行的指令是哪一条。
我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界:执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。