gpt4 book ai didi

c - i386 C 进程 - 剩余的 1 GB 可寻址空间发生了什么?

转载 作者:太空宇宙 更新时间:2023-11-04 05:38:35 25 4
gpt4 key购买 nike

据记载,在堆上分配的变量存储在低地址区域并向堆栈增长,反之亦然。我决定对此进行测试:

#include <stdio.h>
#include <stdlib.h>

const char my_const_global_var = '0';
char my_global_var = '0';

int main(void) {
char my_stack_var = '0';
char* my_heap_var = (char*) malloc(1);
*my_heap_var = '0';
}

看来 my_const_global_varmy_global_var 是在低地址区域(在 000XXXXX 之后和堆之前不久)寻址的,但让我感到惊讶的是my_stack_var 的地址正好在 75% 标记附近(bffbdaXX 附近)。我猜当我的全局/堆/堆栈变量超过 3 GB 内存时,我会遇到段错误,所以我进行了搜索,发现提到了 a 3 GB barrier。但没有提及在剩余的 1 GB 可寻址空间中发生了什么。

剩余 25% 的内存地址空间发生了什么?

最佳答案

在 32 位 x86 CPU 上运行的保护模式操作系统通常将 32 位虚拟地址空间划分为两个主要区域。第一个用于用户进程,第二个用于内核。虚拟地址空间不直接寻址物理内存。相反,它通过内核维护的页表映射到物理内存。这允许操作系统为每个进程提供自己的虚拟地址空间,将它们相互隔离。当它切换进程时,它会更改页表,以便虚拟地址空间的用户区域指向新进程使用的物理内存位置。

然而,当它切换进程时,操作系统不会更改对应于内核区域的页表条目。这意味着虽然每个进程都有自己的物理内存映射到用户区域,但每个进程的内核区域保持不变。将内核内存映射到每个进程的虚拟地址空间可以在执行系统调用时更快地从用户模式转换到内核模式。如果内核没有映射到每个进程,则操作系统基本上必须切换进程(切换到假设的内核“进程”)以执行系统调用。切换进程是比仅从用户模式转换到内核模式更昂贵的操作。

大多数 64 位 x86 操作系统也有类似的分割,但由于它们有更大的虚拟地址空间,它们将虚拟地址空间分成更大的 block 。当运行 32 位程序时,这些操作系统通常允许程序访问所有或几乎所有的前 4 GB 虚拟地址空间。

请注意,虚拟内存如何划分为用户和内核区域不受系统中物理内存量的影响。除非明确配置不同,否则只有 64 MB RAM 的机器在运行完全相同的操作系统时将具有与具有 64 GB 内存的机器相同的用户/内核虚拟地址空间分割。

关于c - i386 C 进程 - 剩余的 1 GB 可寻址空间发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25893835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com