【问题标题】:Address of (&) gives compiler generated address or loader generated address?(&) 的地址给出编译器生成的地址还是加载器生成的地址?
【发布时间】:2012-03-08 06:33:02
【问题描述】:
int a;
printf("address is %u", &a);

这是哪个地址..?我的意思是这是编译器生成的地址,即虚拟地址还是加载程序在 RAM 中给定的物理地址..?

由于它每次打印不同的地址,我想它必须是 RAM 中的地址。只是想确定一下。

请提供任何可以参考您的答案的链接。

【问题讨论】:

  • 最有可能是虚拟的。除非你用真实地址空间编程系统,例如 arduino
  • 如果这是用于 Windows 7 PC 或类似计算机的,那么是的,它将是一个虚拟地址。但在某些系统上,它将是物理内存地址。由于您没有告诉我们您使用的是什么系统,因此无法回答问题。
  • 如果存在虚拟地址到物理地址的转换,则这是一个虚拟地址。如果不是,则为物理的(除非您的程序在解释器或 VM 中运行,在这种情况下,它可能是其他东西)。此地址基于加载程序为您的应用程序选择的位置。由于各种原因,此地址可能会有所不同(例如安全原因或只是上一个位置已被其他东西占用)。

标签: c compiler-construction virtual loader memory-address


【解决方案1】:

为用户空间中的局部变量返回的地址始终是虚拟地址而不是物理地址。

在您的情况下,变量a 分配在本地存储(堆栈)上,每次执行程序时都会为函数分配一个堆栈空间,该变量位于此堆栈帧内的特定偏移处,因为地址每次为变量返回的地址也不同时,分配给程序的堆栈的数量也可能不同。

【讨论】:

  • 总是一个虚拟地址 如果代码在以实模式运行的 CPU 上运行怎么办?假设 CPU 是 x86,甚至。
  • 那为什么每次都不一样..?如果只编译一次,每次运行代码时它都应该返回相同的地址。
  • 不不不...编译器生成的地址是虚拟地址,它是由'&'运算符返回的。那么本地堆栈在哪里出现..?如果返回本地堆栈地址,它是物理的,对吧..?
  • @Adorn:如果在操作系统中有一个地址空间供所有进程使用,并且可以在程序启动之前分配和释放内存,那么您的程序可能无法每次都加载到相同的地址。此外,操作系统可能正在使用Address Space Randomization 来阻止对程序中安全缺陷的持续利用。它通过在不同的地址加载程序来实现这一点,这样漏洞利用就不能依赖于固定的位置。
【解决方案2】:

在任何现代操作系统上,您在 C 级别上看到的所有地址都是虚拟地址。您给出的示例是堆栈上的一个变量,并且每次执行都会有所不同的原因是(虚拟)堆栈地址出于安全原因是随机的。

但无论如何,即使是由加载程序解析的全局符号在进程的地址空间中也有虚拟地址。

(所有这些对于嵌入式设备来说可能并非如此,但这通常不是你在学习 C 时会遇到的)

【讨论】:

    【解决方案3】:

    正确答案是:“视情况而定。”

    (为了明确定义,printf应该使用“%p”指令,并将地址转换为“void *”:

    printf("%p\n", (void *)&a);
    

    尽管使用 %u 毫无疑问适用于您使用的任何标志的特定编译器。)

    正如@Alex 所指出的,如果正在进行翻译(与大多数现代操作系统一样,甚至在虚拟机下以“模拟物理”运行时),地址是虚拟的。如果“a”具有静态存储持续时间,则地址本身通常在链接或加载时确定,但如果没有,则在运行时(如@Als 所说的那样在堆栈上)确定。声明为“静态”或“外部”的变量具有静态持续时间;在函数体外部声明的变量具有静态持续时间;和在函数体中声明的变量,但不使用“extern”或“static”,具有自动存储持续时间(因此通常位于“堆栈”上 - 尽管可以有多个堆栈,如使用 POSIX 线程时)。

    【讨论】:

      【解决方案4】:

      我的意思是这是编译器生成的地址,即虚拟地址或 加载程序在 RAM 中给定物理地址。

      错误的二分法。编译器生成的地址被链接器重定位,&返回的正是这个地址。它是一个虚拟地址,除非您在不使用 VM 的 NetWare 3 等奇怪的东西上运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-20
        • 1970-01-01
        • 1970-01-01
        • 2014-05-24
        • 1970-01-01
        • 1970-01-01
        • 2014-12-10
        • 2015-05-30
        相关资源
        最近更新 更多