首页 > 解决方案 > 为什么我的 C 程序中的虚拟地址如此之大?

问题描述

我最近了解了虚拟内存和分页,编译器只生成从 1 开始的虚拟地址,并且只是向上计数。我想我会对此进行测试,并在下面编写了一个简短的 C 程序,它实例化了一个全局变量并打印了它的地址,期望一个非常小的值,因为 CPU 只看到虚拟地址,但我得到了 4247584。这是怎么回事,我的假设是错误的吗?如果可能的话,什么是显示从 1 开始生成的虚拟地址的程序?

我的程序:

#include <stdio.h>

int x = 0;

int main(){
    printf("%d\n", &x);
    return 0;
}

(我在 Windows 10 上使用 gcc 4.8.1)

标签: cvirtual-memory

解决方案


虚拟地址的实际相对无关紧要(嗯,因为它是虚拟的)。当它不是从 0 开始时,没有什么“浪费”。地址值的唯一前提条件是程序、数据及其所有相关的共享库实际上适合值空间。

然而,出于安全原因,以潜在攻击者无法重现的方式在虚拟地址空间中分配进程的各种代码和数据区域是有意义的(使得固定地址的代码注入攻击几乎 [sic] 不可能),即这就是现代操作系统为程序随机分配虚拟地址空间值的原因。

在某些操作系统(如 Linux)上,您可以关闭虚拟地址空间布局随机化,从而使其可重现。地址很可能仍不会从零开始,因为库和启动代码很可能占用比您自己的程序低的地址。


推荐阅读