我知道C内存布局和二进制形成过程。 我对阶段和何时向全局变量分配地址的阶段有疑问/疑问。
extern int dummy; //Declared in some other file
int * pTest = &dummy;
此代码编译良好。仅在为 pTest 指定地址的情况下,它的地址才为 dummy 。 我想知道 dummy 变量在哪个阶段(编译或链接器)获取地址?
答案 0 :(得分:6)
编译器说:
int *pTest = &<where is dummy?>;
链接器说:
int *pTest= &<dummy is here>;
装载机说:
int *pTest= <dummy is at 0x1234>;
这种稍微简化的解释试图传达以下内容:
编译器标识使用了外部变量dummy
链接器标识此变量所在的位置和模块
但是只有将可执行程序放入内存后,变量的实际位置才是已知的,加载程序会将这个实际地址放置在使用dummy
的所有位置。
答案 1 :(得分:0)
实际过程实际上有所不同。
编译器将有关分配和外部对象引用的信息保存在目标文件中。
根据实际的硬件IS和实现,链接器将计算绝对地址(如果代码将放置在固定地址(例如嵌入式uC项目))或相同的虚拟地址,并在重定位表中设置条目(如果代码是与位置无关的),并且在程序加载和启动过程中,加载程序正在将该虚拟地址更改为正确的地址。