问题 3.7
编程,将10000H~1000FH这段空间当作栈,初始状态栈是空的,将AX、BX、DS中的数据入栈。
思考后看分析。
分析:
代码如下。
mov ax,1000H
mov ss,ax ;设置栈的段地址,SS=1000H,不能直接向段寄存器SS中送入数据,所以用ax中转。
mov sp,0010H ;设置栈顶的偏移地址,因栈为空,所以sp=0010H。如果
;对栈为空时SP的设置还有疑问,复习3.7节、问题3.6
;上面的三条指令设置栈顶地址。编程中要自己注意栈的大小。
push ax
push bx
push ds
问题 3.8
编程:
(1)将10000H~1000FH这段空间当作栈地址,初始状态是空的;
(2)设置AX=001AH,BX=001BH
(3)将AX、BX中的数据入栈;
(4)然后将AX、BX清零;
(5)从栈中恢复AX、BX原来的内容。
思考后看分析。
分析:
代码如下。
mov ax,1000H
mov ss,ax
mov sp,0010H ;初始化栈顶,栈的情况如图3.15(a)所示
mov ax,001AH
mov bx,001BH
push ax
push bx ;ax、bx入栈,栈的情况如图3.15(b)所示
sub ax,ax ;将ax清零,也可以用mov ax,0,
;sub ax ax的机器码为2个字节,
;mov ax,0的机器码为3个字节。
sub bx,bx
pop bx ;从栈中恢复ax,bx原来的数据,当前栈顶的内容是box中原来的内容:
pop ax ;001HB,ax中原来的内容001AH在栈顶的下面,所以要先pop bx,然后再pop ax。
从上面的程序我们看到,用栈来暂存以后需要恢复的寄存器中的内容时,出栈的顺序要和入栈的顺序相反,因为最后入栈的寄存器的内容在栈顶,所以在恢复时,要最先出栈。
问题 3.9
编程:
(1)将10000H~1000FH这段空间当作栈,初始状态栈为空的;
(2)设置AX=001AH,BX=001BH;
(3)利用栈,交换AX和BX中的数据。
思考后看分析。
分析:
代码如下。
mov ax,1000H
mov ss,ax
mov sp,0010H ;初始化栈顶,栈的情况如图3.16(a)所示
mov ax,001AH
mov bx,001BH
push ax
push bx ;ax、bx入栈,栈的情况如图3.16(b)所示
pop ax ;当前栈顶的数据是bx中原来的数据:001BH
;所以先pop ax,ax=001BH
pop bx ;执行pop ax后,栈顶的数据为ax原来的数据;
;所以再pop bx,bx=001AH;
问题 3.10
如果要在10000H处写入字型数据2266H,可以用以下的代码完成:
mov ax,1000H
mov ds,ax
mov ax,2266H
mov [0],ax
补全下面的代码,使他能够完成同样的功能:在10000H处写入字型数据2266H。
要求:不能使用“mov 内存单元,寄存器”这类指令。
_____________
_____________
_____________
mov ax,2266H
push ax
思考后看分析。
分析:
我们来看需补全代码的最后两条指令,将ax中的2266H压入栈中,也就是说,最终应由push ax将2266H压入10000H处。问题的关键就在于:如何使push ax访问的内存单元是10000H。
push ax是入栈指令,它将在栈顶之上压入新的数据。一定要注意:它执行过程是,先将记录栈顶偏移地址的SP寄存器中的内容减2,使得SS:SP指向新的栈顶单元,然后再将寄存器中的数据送入SS:SP指向的新的栈顶单元。
所以,要在执行push ax之前,将SS:SP指向10002H(可以设SS=1000H,SP=0002H),这样,在执行push ax的时候,CPU先将SP=SP-2,使得SS:SP指向10000H,再将ax中的数据送入SS:SP指向的内存单元处,即10000H处。
完整的程序如下。
mov ax,1000H
mov ss,ax
mov sp,2
mov ax,2266H
push ax
从问题3.10的分析可以看出,push、pop实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。同时,push和pop指令还要改变SP中的内容。
我们要十分清楚的是,push和pop指令与mov指令不同,CPU执行mov指令只需一步操作,就是传送,而执行push、pop指令却需要两步操作。执行push时,CPU的两步操作是:先改变SP,后向SS:SP处传送。执行pop时,CPU的两步操作是:先读取SS:SP处的数据,后改变SP。
注意,push、pop等栈操作指令,修改的知识SP。也就是说,栈顶的变化范围最大为:0~FFFFH。
提供:SS、SP指示栈顶;改变SP后写内存的入栈指令;读内存后改变SP的出栈指令。这就是8086CPU提供的栈操作机制。
栈的综述
- 8086CPU提供了栈操作机制,方案如下。
- 在SS、SP中存放栈顶的段地址和偏移地址;
- 提供入栈和出栈指令,它们根据SS:SP指示的地址,按照栈的方式访问内存单元。
- push指令的执行步骤:①SP=SP-2;②向SS:SP指向的字单元中送入数据。
- pop指令的执行步骤:①从SS:SP指向的字单元中读取数据;②SP=SP+2
- 任意时刻,SS:SP指向栈顶元素。
- 8086CPU只记录栈顶,栈空间的大小我们要自己管理。
- 用栈来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序要和入栈的顺序相反。
- push、pop实质上是一种内存传送指令,注意它们的灵活运用。
栈是一种非常重要的机制,一定要深入理解,灵活掌握。