#pragma once
/* 18-寄存器(内存访问)06
push、pop指令
问题
编程: 将10000H~1000FH 这段空间当作栈,初始状态是空的,将 AX、BX、DS中的数据入栈。 描述的有点迷,这一道题的意思就是,让我们先把10000H 设置成栈顶,把1000FH,设置成栈底,然后把AX,BX,DS 的数据push进栈.
mov bx,1000H
mov ss,bx
mov sp,0010H 注意SP 只是设置栈顶的偏移地址,SP不是段寄存器,可以用mov 进行赋值
push ax
push bx
push ds push 和 pop 指令可以对段寄存器使用
问题
编程:
(1)将10000H~1000FH 这段空间当作栈,初始状态是空的;
(2)设置AX=001AH,BX=001BH;
(3)将AX、BX中的数据入栈;
(4)然后将AX、BX清零;
(5)从栈中恢复AX、BX原来的内容。
mov bx,1000H
mov ss,bx
mov sp,0010H
mov ax,001AH
mov bx,001BH
push ax
push bx
sub ax,ax 也可以用mov ax,0
sub bx,bx sub bx,bx 机器码为2个字节, mov 指令机器码为3个字节,所以能省就省
pop bx
pop ax
从上面的程序我们看到,用栈来暂存以后需要恢复的寄存器中的内容时 ,出栈的顺序要和入栈的顺序相反,因为最后入栈的寄存器的内容在栈顶 ,所以在恢复时,要最先出栈。***********重点*************
问题
编程:
(1)将10000H~1000FH 这段空间当作栈,初始状态是空的;
(2)设置AX=002AH,BX=002BH;
(3)利用栈 ,交换 AX 和 BX 中的数据。
mov bx,1000H
mov ss,bx
mov sp,0010H 经过几次锻炼我们应该能发现,如果我们要手动的设置空栈的 栈底的话,那么就应当设置为 栈最高位地址 + 1H 就对了.
mov ax,002AH
mov bx,002BH
push ax
push bx
pop ax
pop bx
问题
我们如果要在10000H处写入字型数据2266H,可以用以下的代码完成:
mov ax,1000H
mov ds,ax
mov ax,2266H
mov [0],ax
看题目:
补在10000H处写入字型数据2266H。
__________ mov ax,1000H push 1000H 这两种都可以的
__________ mov ss,ax pop ss
__________ mov sp,2 mov sp,2 因为SP 置与超出栈底2的位置,当我们要push 的时候还会sp= sp-2 所以又指定到10000H 那里了
mov ax,2266H
push ax
要求:不能使用“mov 内存单元,寄存器”这类指令
结论
push、pop 实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。
同时,push和pop指令还要改变 SP 中的内容。
我们要十分清楚的是,push和pop指令同mov指令不同,CPU执行mov指令只需一步操作,就是传送,而执行push、pop指令却需要两步操作。
执行push时:
先改变SP,后向SS:SP处传送。
执行pop时:
先读取SS:SP处的数据,后改变SP。
注意
push、pop 等栈操作指令,修改的只是SP。也就是说,栈顶的变化范围最大为:0~FFFFH。
提示:SS、SP指示栈顶;改变SP后写内存的入栈指令;读内存后改变SP的出栈指令。
这就是8086CPU提供的栈操作机制。
栈的综述(总结)
(1)8086CPU提供了栈操作机制,方案如下:
在SS,SP中存放栈顶的段地址和偏移地址;
提供入栈和出栈指令,他们根据SS:SP指示的地址,按照栈的方式访问内存单元。
(2)push指令的执行步骤:
(1)SP=SP-2;
(2)向SS:SP指向的字单元中送入数据。
(3)pop指令的执行步骤:
(1)从SS:SP指向的字单元中读取数据;
(2)SP=SP+2。
(4)任意时刻,SS:SP指向栈顶元素。
(5)8086CPU只记录栈顶,栈空间的大小我们要自己管理。 (我们可以欺骗CPU啊~读取其他的东西.)
(6)用栈来暂存以后需要恢复的寄存器的内容时 ,寄存器出栈的顺序要和 入栈的顺序相反。
(7)push、pop实质上是一种内存传送指令,注意它们的灵活应用。
栈是一种非常重要的机制,一定要深入理解,灵活掌握。
*/