内存中的堆栈实际上是一个堆栈吗?

5

在内存中,有一个名为堆栈的部分,它从顶部开始向下增长,直到堆区。这个堆栈和LIFO堆栈是一样的吗?底部的堆是否是FIFO?

当你执行“push”和“pop”操作时,会改变内存中的堆栈吗?

5个回答

4

3
是的,计算机架构使用LIFO堆栈来存储诸如返回地址、本地变量等内容。来自维基百科
x86架构具有执行堆栈机制的硬件支持。指令(例如push、pop、call和ret)与正确设置的堆栈一起使用,用于传递参数,为本地数据分配空间,并保存和恢复调用-返回点。ret size指令非常有用,可用于实现空间高效(且快速)的调用约定,其中被调用方负责回收由参数占用的堆栈空间。
例如,当调用函数时,架构将返回地址、当前寄存器值等推送到堆栈上。当函数返回时,该数据从堆栈中弹出,以便在先前位置恢复执行。

2

内存有一个很大的堆栈,但是有一个指向堆栈顶部的栈指针。在push时,它会上升,在pop时,它会下降。但通常你可以通过修改指针来作弊,这样你就可以得到一个已经被弹出的值。

并不是所有的体系结构都将堆栈定向相同。最终这一点并不重要。有些系统在push时增加堆栈指针,在pop时减少;另一些系统则在push时减少堆栈指针,在pop时增加。

例如:栈指针位于0x100,并且它是一个递增的系统。 然后你push,栈指针位于0x104。再次push,位于0x108。pop回到0x104。 另一个系统将从0x100开始,向下推到0xfc,然后推到0xf8,并弹回到0xfc。如果你再次pop,你回到了0x100。如果你从栈指针中减去8,它就回到了0xf8,所以你可以再次pop它们。(或者,C编译器在函数结束时会执行的操作,只需从栈指针中添加/减去12,而不是用三个指令弹出3个局部变量。)


1
我不确定你所说的“实际上是一个堆栈”(什么是“真正”的堆栈?),但在概念上它是相同的:push 函数会减小“堆栈指针”,而 pop 函数会增加它。

我在谈论使用push和pop的堆栈。 - node ninja

1
你所说的“堆栈”是程序的调用堆栈,因此从这个意义上讲它是一个堆栈。但实际上它并不需要是一个堆栈:具体实现取决于硬件、操作系统和语言运行时——我曾经使用过将调用堆栈实现为[双向]链表的C编译器,分配在堆上,类似于IBM大型机操作系统的做法。
Intel/Windows风格的固定大小硬件堆栈的缺点是使得环境不太适合递归。另一方面,它使得增加堆栈非常高效,因为你不必使用操作系统资源来从堆中分配内存:只需增加指针即可。

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