我昨天突然怀疑。我已经用C编程了很长时间。我的问题是:
假设有一个变量
static uint32_t count = 0;
这个变量应该存储在数据段中。为了这个例子,让我们假设数据段从进程的4GB虚拟内存空间中的偏移0x08000000
开始。
我知道在偏移0x08000000
之后的某处,为变量'count'保留了4个字节,值为0。
我的问题是内存中的这个4字节值如何与名称“count”和类型“uint32_t”相关联(或者它是4字节长而不是6字节长的事实。)
根据以下答案,似乎地图信息存储在"symbol table"
似乎暗示它必须是内存中最终可执行文件的一部分。如果符号表存储在哪里?它在代码/文本段中吗?
答案 0 :(得分:3)
就生成的机器代码而言,名称“count”不存在。它只知道加载和存储数据的地址。类似地,类型信息不会被保留,因为为了操作这个变量而生成的机器代码是在正确的大小和signed-ness下生成的,因此它执行4字节的加载和存储,以及无符号的32位算术运算。数据
对于调试和动态链接目的,该信息可能在其他地方可用。带符号的二进制文件将有一个表,列出全局变量所在的地址或偏移量,以及它们的类型。
答案 1 :(得分:2)
与名称关联:可执行文件有一个符号表,它提供有关名称和相应地址的动态链接器信息(实质上是一个映射),或者如果可执行文件被剥离,则根本没有名称,只有原始地址被提及。
与类型的关联:只需编译器生成将该地址视为4字节无符号整数的开头的代码(例如,在DWORD
上运行的指令等)。
答案 2 :(得分:1)
当编译器解析您的代码时,它会使数据结构保留有关它在程序中看到的类型和变量的信息。所以,当解析器看到:
static uint32_t count = 0;
它记录了一个变量count
,其类型为uint32_t
,静态存储持续时间初始化为零。当解析器再次遇到标识符count
时,它知道它引用了上述变量。生成目标代码时使用所有这些信息,因此编译器后端知道为其分配空间,并将其视为无符号整数。此信息可能最终在目标文件上,用于调试,或者如果它不是静态变量,它可能最终在一个部分供动态链接器使用。
加载器不需要此信息,因此如果它仍然存在于目标文件中,则不需要加载它。链接器和动态链接器可能需要导出符号的信息,因此它们从相应的部分加载它。