4

我对exe堆栈的位置有点困惑。我知道程序运行之前的CRT通过分配一定数量的堆来初始化堆(这又是由分配页面的操作系统分配的),但是在哪里堆?也是在页面上吗?还是通过在 GDT 上使用 ring3 描述符在用户模式 ​​(ring3) 中的所有程序共享它(我认为不是,但我不确定)?

4

3 回答 3

5

Windows 将为每个线程保留一个连续的虚拟内存区域(默认为 1MB)。然后它提交该内存区域的几个最顶层页面,并将其下方的一对标记为保护页面。随着线程的堆栈向下增长,如果访问保护页面,则会发生异常,Windows 提交保护页面并将其下方的页面标记为保护。

您可以使用出色的SysInternals实用程序VMMap来探索此行为。以下是该工具的一个片段:

在此处输入图像描述

于 2012-09-15T12:16:11.857 回答
3

每个线程都有自己的堆栈。它只是为此目的分配的一块内存。

所有内存都在页面中分配,包括堆栈(在 Windows 上,我相信堆栈默认为 1MB,因此它会跨越多个页面,因为大多数内存页面都是 4KB。)

但它实际上只是堆栈指针寄存器指向的一块内存。

于 2012-09-15T11:20:25.627 回答
1

Windows 中的每个程序都是一个进程。进程通常不会在彼此之间共享它们的记忆。

共享与不共享是每个进程的虚拟地址空间如何映射到物理内存的问题。

如果两个进程将其地址空间的一部分映射到物理内存的相同页面上,则该内存由它们有效地共享,并且每个进程都可以读取并可能写入它并观察另一个进程的写入。

共享堆栈内存几乎没有意义,因此每个进程都有自己的堆栈。实际上,进程更像是容器。执行代码和使用堆栈的实体是线程。每个进程中至少有一个线程。线程有自己的栈,但由于一个进程的线程在同一个虚拟地址空间中,它们可以访问彼此的栈。有时在线程之间共享堆栈数据很有用,但应该小心执行,以免破坏线程状态并导致挂起或崩溃。

于 2012-09-15T11:29:59.643 回答