汇编学习-栈
CPU 如何指导当前要执行的指令所在的位置?
答:寄存器 CS 和 IP 中存放着当前指令的段地址和偏移地址
8086 CPU 中,有两个寄存器:
段寄存器 SS 存放栈顶的段地址
寄存器 SP 存放栈顶的偏移地址
任意时刻,SS:SP 指向栈顶元素
push ax 内部实现:
(1)SP = SP - 2;
(2)将 ax 中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶
pop ax 内部实现正好相反,SP + 2,取出数据,指向新栈顶
换个角度看:
任意时刻,SS:SP 指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素
所以 SS:SP 只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址 +2
栈最底部字单元的地址为 1000:000E,所以栈空时,SP = 0010H (000E + 2 = 0010)
如果将 10000H~1000FH 这段空间当作栈,初始状态栈是空的,此时,SS = 1000H,SP = 0010H,看下图
注意:
出栈后,SS:SP 指向新的栈顶 1000EH,pop 操作前的栈顶元素,1000CH 处的 2266H 依然存在,但是,它已不在栈中
当再次执行 push 等入栈指令后,SS:SP 移至 1000CH,并在里面写入新的数据,它将被覆盖
栈空间当然也是内存空间的一部分,它只是一段可以以一种特殊的方式进行访问的内存空间。
push 和 pop 指令的格式
push 寄存器:将一个寄存器中的数据入栈
pop 寄存器:出栈,用一个寄存器接收出栈的数据
比如:push ax pop bx (将出栈的数据放入 bx 寄存器中)
push 段寄存器:将一个段寄存器中的数据入栈
pop 段寄存器:出栈,用一个段寄存器接收出栈的数据
比如:push ds pop es
通用寄存器都是以 x 结尾的,段寄存器都是以 s 结尾的
结论:
push、pop 实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与 mov 指令不同的是,push 和 pop 指令访问的内存单元的地址不是在指令中给出的,
而是由 SS:SP 指出的。
注意:
push、pop 等栈操作指令,修改的只是 SP,也就是说,栈顶的变化范围最大为:0~FFFFH
push 指令的执行步骤:
1)SP = SP - 2;
2)向 SS:SP 指向的字单元中送入数据
pop 指令的执行步骤:
1)从 SS:SP 指向的字单元中读取数据
2)SP = SP + 2;