1

首先,我将展示对堆栈的理解不足,然后我将提出一个无法很好回答的略微连贯的问题,因为该问题不够具体,无法引出一个有条理的答案。

那么,当程序运行时,函数被压入堆栈——这意味着堆栈指针是递增还是递减?

堆栈内存分配中究竟存储了什么?指向变量数据的指针,指向程序 est 的指针?我只是不明白堆栈中到底存储了什么(什么数据类型,什么类型的引用,它们是如何存储的)我希望一个函数存储它的局部变量指针和一个指向调用它的地址的指针,以便它可以返回.

此外,windows x86 虚拟内存分配实际上将单个虚拟内存块映射到任意多个物理内存地址,因此堆栈在 windows x86 系统的物理内存中是连续的还是不连续的?

最后,假设堆栈存储在 x86 上 32 位窗口上的应用程序的用户分配的虚拟内存中,堆栈指针(引用内存的高地址还是低地址?)是 31 位的(31 是因为用户分配的并且高2GB保留给内核分配)小端引用,对吗?

当数据到达堆栈时(就像一个函数被输入并为一个新的 DWORD 分配内存)存储在该 DWORD 中的数据被推入堆栈并且堆栈指针是递增还是递减?系统如何同时感知堆栈的两端?

---- ESP在这里?

|-变量x的引用地址

|- 函数 1 中变量 x 的内存地址中要存储的整数数据

|----上面的功能1块^^

|

|

---- 还是这里的 ESP?

并且从这里引用地址和整数数据将被弹出到寄存器中,并且 mov 操作会将整数数据存储在分配的内存位置?

当新数据进入堆栈时,我听说堆栈“向下”增长,但这似乎不合理,因为只有更高和更低的内存地址 - 我知道只有堆栈的一端需要递增/递减,但它是高地址或低地址,堆栈长度(高度)如何分隔?当堆栈“增长”过大时,系统如何理解?

抱歉所有问题,但我已经做了很多阅读,用于描述我一直在阅读的概念的术语在我的词汇表中没有很好地操作。此外,我在谷歌、维基百科和这个网站上查了一下,找不到解决我具体问题的解释。

谢谢。

4

2 回答 2

3

行。堆栈只是一种抽象数据类型。好的。一个内存数组,您可以将数据放置(puhs)到末尾并移除(pop)它。向上或向下增长,从前面或后面,或任何取决于它的实现方式。好的。

现在 (a) 系统堆栈更加明确。它是由程序分配的 RAM 区域,或本地线程存储或其他任何东西。指针被放置在其内存位置的“末端”,并且向顶部生长。推送将数据放在当前位置的堆栈上(减去数据大小,使其不会超过末尾),因此在写入之前递减。强制时,新的堆栈指​​针指向最后一个“推送”值的开始。

为什么要倒退?约定和易用性。考虑一个嵌入式系统或一些具有更多有限 RAM 资源的旧系统。如果我们让堆从 RAM 的顶部开始——就在代码和静态/常量数据之后,并且我们需要在同一个 RAM 空间中使用另一种类型的存储,为什么不让它从后面增长呢?这样您就不必担心每个部分必须有多大。当所有 RAM 都用完后,它们将在中间某个地方相遇(并且下一次写入将通过堆栈溢出而繁荣)。易于维护和创建且高效 - 无需猜测适当的大小等。

就从这里开始吧。在这一点上,虚拟地址等不应该让你太担心。当空间不足时,它们只是帮助“繁荣”部分。我怀疑堆栈是否会分成多个页面,但如果是,让操作系统处理它,一切都很好(而且速度很慢,但那是另一回事了。)

现在堆栈上发生了什么 - 无论您想要什么。通常,传递给函数的参数超出了可以放入寄存器的范围,在函数之外不需要的作用域变量,有时用于 this 指针的 c++ 胶水,有时更多alloca()用于将堆栈视为动态内存 - 你会看到这在线程代码中通常有助于防止内存写入竞争条件等。此外,不适合寄存器的值返回的值通常也会返回到堆栈中。基本上,您在函数中看到的每个本地变量都有很大的机会在某个时候存在于堆栈中,因为寄存器已填满并且需要更多空间。因此,许多系统试图确保堆栈内存尽可能快。

要回答您剩下的问题 - 系统可能知道也可能不知道堆栈的两侧 - 取决于平台。我猜windows是通过跟踪如果写入超出结束位置来了解堆栈开始的。不成对的推送/弹出会破坏程序的一天,有时还会导致操作系统挂起(现在更少了)。我无法回答您的 Windows 特定 32/31 位地址问题,因为我在那里没有直接经验。其他人可以抓住那部分。最后,堆栈增长方向是令人困惑的术语。我通常认为系统堆栈是“向上”增长的,但这可能只是我。

希望这对您有所帮助并解决一些问题!

于 2013-02-14T17:40:07.493 回答
1

当程序运行时,函数被推入堆栈 - 这意味着堆栈指针是递增还是递减?

这取决于堆栈的实现方式。如果它从内存的末尾向后增长,它就会递减。如果它从内存的开头向前增长,则递增。

堆栈内存分配中究竟存储了什么?

任何给定的程序或编程语言都压入堆栈。这可以包括返回地址、值类型、指向对象的指针和堆栈帧。

windows x86虚拟内存分配实际上将单个虚拟内存块映射到任意多个物理内存地址,因此堆栈在windows x86系统的物理内存中是连续的还是不连续的?

见这里:http ://www.dirac.org/linux/gdb/02a-Memory_Layout_And_The_Stack.php

当堆栈“增长”过大时,系统如何理解?

它到达堆的顶部。

于 2013-02-14T17:40:20.120 回答