8086中的堆栈段和堆栈指针

5
我对堆栈段(ss)和堆栈指针(sp)寄存器有点困惑。 当堆栈为空时,sp的值是否等于ss的值? 我了解到,当我们将一个字(2字节)推入堆栈时,sp会减少2个单位。如果第一个陈述是真的(sp=ss),那么我可以说,如果堆栈不为空,堆栈指针的值始终小于或等于堆栈段的值,这是真的吗? 如果我们将一个值赋给sp,使其大于ss会发生什么?例如: mov ss,200h mov sp,400h mov ax,1010h push ax
请纠正任何错误,提前感谢。
2个回答

8
不,ss 就像其他段寄存器一样,例如 csds。它们按照通常的实模式规则参与形成物理地址,如 address = 16 * segment + offset,其中堆栈的偏移量来自 sp。因此,最后一个推入堆栈的项目地址为 16 * ss + sp。除非您事先知道堆栈末尾的位置,否则无法确定堆栈是否为空,而且 sssp 的数值比较根本没有意义。

4
堆栈段(ss)寄存器和堆栈指针(sp)寄存器用于创建指向堆栈的不同地址部分:
ss  aaaaaaaaaaaaaaaa----
sp  ----aaaaaaaaaaaaaaaa

使用的地址为ss * 16 + sp。段寄存器选择整个1024 kB内存空间中的64 kB段,而堆栈指针是该段内的偏移量。

当堆栈为空时,堆栈指针指向为堆栈分配的空间顶部。

例如,如果ss寄存器包含0200h,则堆栈段从02000h到11fffh。然而,实际堆栈可能比堆栈段小。如果堆栈大小为16 kB,则sp从4000h开始,并在堆栈增长时向0000h移动。


谢谢@Guffa,但是你所说的“堆栈指针指向为堆栈分配的空间顶部”是什么意思?在这种情况下,sp包含什么?在你给出的例子中ss=200h,当推送数据时,sp如何改变以使段从020000h到02ffff h? - Oussama Guessoum
@OussamaGuessoum:当ss = 0200h时,sp中的0000h到ffffh值可用于到达地址020000h至02fffffh,因为地址为ss * 16 + sp。如果ss为0200h且sp从4000h开始,并推送一个字节,则sp将更改为3fffh,并且该字节最终位于地址023fffh。 - Guffa
好的,图像变得更清晰了,非常感谢。如果 sp 包含 0000h 并且我们尝试推送一个字节,或者 sp 包含 ffffh 并且我们尝试弹出一个字节,会发生什么?这是否是堆栈溢出?我从你那里学到了很多,感谢你的帮助 :) - Oussama Guessoum
@Guffa,SS=0200h 的示例是错误的!堆栈应该从 02000h 到 011FFFh - Sep Roland
我读到sp总是指向堆栈的顶部,即最后推送的字节。在你的例子中,如果sp从4000h开始并且我推送一个字节,则sp会减少到3fffh,然后将字节写入ss:[3fffh]。但是以这种方式,我似乎无法写入ss:[4000h]。即使sp从ffffh开始,也无法在ss:[ffffh]中写入任何内容。 对此有什么想法吗?我找不到任何相关参考资料。 - Nicola
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接