【问题标题】:How is a value in memory associated with a variable and its type? [duplicate]内存中的值如何与变量及其类型相关联? [复制]
【发布时间】:2013-02-07 17:51:59
【问题描述】:

我昨天突然怀疑。我已经用 C 编程很长时间了。我的问题是这样的:

假设有一个变量

static uint32_t count = 0;

这个变量应该存储在数据段中。为了这个例子,我们假设数据段在进程的4GB虚拟内存空间中的偏移量0x08000000开始。

我知道在偏移量0x08000000 之后的某处,为变量“count”保留了 4 个字节,值为 0。

我的问题是内存中的这个 4 字节值如何与名称“count”和类型“uint32_t”相关联(或者它是 4 字节长而不是 6 字节长的事实。)

从下面的答案看来,映射信息存储在"symbol table"

这似乎表明它必须是内存中最终可执行文件的一部分。如果是这样,符号表存储在哪里?它在代码/文本段中吗?

【问题讨论】:

  • 感谢链接器和后续的加载器,因为它们为您解决了所有这些问题。 (除了类型部分,它留给编译器)。

标签: c pointers memory static


【解决方案1】:

就生成的机器码而言,名称“count”是不存在的。它只知道加载和存储数据的地址。类似地,类型信息不会保留,因为生成用于操作此变量的机器代码是为了对正确的大小和符号进行操作,因此它执行 4 字节加载和存储,以及无符号的 32 位算术运算数据。

出于调试和动态链接的目的,该信息可能在其他地方可用。带有符号的二进制文件会有一个表格,列出全局变量所在的地址或偏移量,以及它们的类型。

【讨论】:

  • 没错。除非另有说明(例如在 GCC 上使用 -g 标志),否则二进制文件没有像 count 这样的标签概念。对变量的任何引用都使用带有 32 位操作的原始地址。
【解决方案2】:

与名称的关联:或者可执行文件有一个符号表,它提供有关名称和相应地址的动态链接器信息(本质上是一个映射),或者如果可执行文件被剥离,则根本没有名称,只有原始地址被引用。

与类型的关联:只需编译器生成将该地址视为 4 字节无符号整数开头的代码(例如,在 DWORDs 上运行的指令等)

【讨论】:

    【解决方案3】:

    当编译器解析您的代码时,它会保存数据结构,其中包含有关它在程序中看到的类型和变量的信息。所以,当解析器看到:

    static uint32_t count = 0;
    

    它记录了一个变量count,类型为uint32_t,静态存储持续时间初始化为零。当解析器再次遇到标识符count时,它就知道它引用了前面提到的变量。所有这些信息都在生成目标代码时使用,因此编译器后端知道为其分配空间,并将其视为无符号整数。此信息可能会出现在目标文件中,用于调试,或者如果它不是静态变量,则可能会出现在供动态链接器使用的部分中。

    加载器不需要此信息,因此如果它仍然存在于目标文件中,则不需要加载它。链接器和动态链接器可能需要导出符号的信息,因此它们从相应的部分加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-02
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多