一、内存中字的存储
1、任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。
2、内存单元是字节单元,则一个字要用两个地址连续的内存单元来存放
3、字单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成
二、DS和[address]
1、CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中,内存地址由段地址和偏移地址…
2、8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。
3、mov指令可以完成基本传送:Ⅰ.将数据直接送入寄存器 mov ax,100H
Ⅱ.将一个寄存器中的内容送入另一个寄存器 mov bx,ax
特殊:Ⅲ.将一个内存单元中的内容送入一个寄存器
[…]表示一个内存单元,[…]中的0表示内存单元的偏移地址
4、如何用mov指令从10000H中读取数据??
<1> 1000H用段地址和偏移地址表示1000:0;
<2> 先将段地址1000H放入DS,然后mov al,[0] 完成传送
5、从内存单元到寄存器的格式:mov 寄存器名,内存单元地址
从寄存器到内存单元的格式:mov 内存单元地址, 寄存器名
6、写几条指令,将al中的数据送入内存单元10000H中?
mov bx,1000H
mov ds,bx
mov [0],al
三、栈
1、基操作:入栈和出栈
入栈:将一个新的元素放到栈顶
出栈:从栈顶取出一个元素
2、栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出
3、CPU提供的栈的机制:
<1> 8086提供入栈和出栈指令:push(入栈) pop(出栈)
<2>push ax;将寄存器ax中的数据送入栈中;
pop ax;从栈顶取出数据送入ax
<3>8086CPU的入栈和出栈操作都是以字为单位进行的
4、CPU如何知道当前要执行的指令所在的位置??
寄存器CS和IP中存放着当前指令的段地址和偏移地址。
8086CPU中,有两个寄存器:
段寄存器SS:存放栈顶的段地址
偏移地址寄存器SP:存放栈顶的偏移地址
任意时刻,SS:SP指向栈顶元素
5、push指令的执行过程(pop 指令的执行过程)
<1>SP=SP-2 (将SS:SP指向的内存单元处,取出数据)
<2>将ax中的内容送入SS: SP指向的内存单元处,SS:SP此时指向新栈顶 (SP=SP+2)
<3>栈的伸展方向是向下的,栈顶是低地址,栈底是高低址
6、如果我们将10000H~1000FH这段空间当作栈,初始状态是空的,此时,SS=1000H,SP=?
栈空,SS:SP指向栈空间最高地址单元的下一个单元;执行 push ax后,SS:SP指向栈中的第一个元素,即SP=10010H
7、总结:
<1>将10000H~1000FH这段空间当作栈段,SS=1000H,栈空间大小为16字节,栈最底部的字单元地址为1000:000E
<2>任意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=000EH
<3>执行push时,先改变sp,后向ss: sp处传送;执行pop时,先读取ss:sp处的数据,后改变sp
8、push、pop指令是可以寄存器和内存之间传送数据的
四、栈顶越界的问题
1、SS和SP只记录了栈顶的地址,依靠SS和SP可以保证在入栈和出栈时找到栈顶
2、可是,如何能够保证在入栈、出栈时,栈顶不会超出栈空间?
3、当栈满的时候在使用push指令入栈,栈空的时候在使用pop指令出栈,都将发生栈顶越界问题
4、push、pop等栈操作指令,修改的只是sp,也就是说,栈顶的变化范围最大:0~FFFFH