【问题标题】:Is the stack in memory actually a stack?内存中的堆栈实际上是堆栈吗?
【发布时间】:2011-08-01 18:07:32
【问题描述】:

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

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

【问题讨论】:

    标签: memory heap-memory terminology stack-memory


    【解决方案1】:

    stack 实际上是一个 LIFO 堆栈。

    它是在程序运行时由程序本身创建的。控制堆栈的代码是在编译时创建的。

    延伸阅读:

    Hardware Stacks

    Call Stack

    X86 Addressing Modes

    【讨论】:

      【解决方案2】:

      是的,计算机体系结构使用 LIFO 堆栈来存储诸如返回地址、局部变量等内容。来自Wikipedia

      x86 架构具有对执行堆栈机制的硬件支持。 push、pop、call 和 ret 等指令与正确设置的堆栈一起使用,以传递参数、为本地数据分配空间以及保存和恢复调用返回点。 ret size 指令对于实现空间高效(和快速)调用约定非常有用,其中被调用者负责回收参数占用的堆栈空间。

      例如,当调用函数时,架构会将返回地址、当前寄存器值等压入堆栈。当函数返回时,该数据会从堆栈中弹出,因此可以在之前的位置继续执行。

      【讨论】:

        【解决方案3】:

        这是一大堆内存,但是有一个栈指针指向栈顶。推时上升,弹出时下降。但通常你可以通过修改指针来作弊,这样你就可以取回一个已经弹出的值。

        并非所有架构的堆栈都朝着同一个方向发展。最后一点都不重要。一些系统使堆栈指针在 push 时增加,在 pop 时减少,其他系统在 push 时减少,在 pop 时增加。

        示例:堆栈指针位于 0x100,它是一个递增系统。 然后你推,堆栈指针在 0x104。你再次推动,在 0x108。你弹出,回到 0x104。 另一个系统将从 0x100 开始,向下推到 0xfc,然后向下推到 0xf8,然后弹回到 0xfc。如果你再次弹出,你会回到 0x100。如果然后从堆栈指针中减去 8,它会回到 0xf8,因此您可以再次弹出它们。 (或者,C 编译器在函数末尾会做什么,只需从堆栈指针中加/减 12,而不是在 3 条指令中弹出 3 个局部变量。

        【讨论】:

          【解决方案4】:

          我不确定您所说的“实际上堆栈”是什么意思(什么是“真正的”堆栈?),但它在概念上是一样的:push 递减“堆栈指针”, pop 增加它。

          【讨论】:

          • 我说的是使用 push 和 pop 的堆栈。
          【解决方案5】:

          您所说的“堆栈”是程序的调用堆栈,因此从这个意义上说,它是一个堆栈。但是没有必要这样:实际的实现是特定于硬件、操作系统和语言运行时的——我使用了 C 编译器,其中调用堆栈被实现为堆栈帧的 [双重] 链表,分配在堆,类似于 IBM 大型机操作系统的处理方式。

          Intel/Windows 风格的固定大小硬件堆栈的缺点是它使环境对递归不太友好。 OTOH,它使堆栈的增长非常有效,因为您不必使用操作系统资源来分配堆外的内存:它只是增加一个指针。

          【讨论】:

            猜你喜欢
            • 2016-08-13
            • 2017-08-18
            • 2011-07-02
            • 2018-09-27
            • 2011-02-11
            • 2016-02-26
            • 2017-07-04
            • 1970-01-01
            • 2018-10-29
            相关资源
            最近更新 更多