内存地址:链接器与。装载机

Memory Addresses: Linker Vs. Loader

我试图了解内存分配在程序编译和加载的不同阶段是如何工作的。

1) 编译器和汇编器生成从地址 0 开始的代码和数据段。

2) 链接器通过关联内存位置重新定位这些节 每个符号定义,然后修改所有引用 到这些符号,以便它们指向这个内存位置。

3) 加载程序在进程的上下文中将程序加载到主内存,并且
因此正是在这一步完成了分页和所有与内存管理相关的操作。

我的问题是关于两件事:

1)链接器分配的地址与加载器分配的地址有何关系。我们可以将链接器地址称为虚拟地址吗?

2)是否所有程序都具有相同的虚拟地址(最终映射到不同的物理地址?)

通常,编译器会生成不从任何特定地址开始的可重定位代码。在某些情况下,这是完全不可能的。例如

int x ;
int *y = &x ;

这些需要特殊处理。

链接器合并了编译器引用的程序段。链接的输出是一个程序,它指示加载程序如何将程序放入内存中。这些说明将处理上述情况。

加载器遵循链接器给出的指令。

1)How are the addresses assigned by the linker related to the ones assigned by the loader. can we call linker addresses virtual addresses?

链接器通常会生成可重定位代码,除非编译器或程序集生成了无法重定位的代码。链接器不产生虚拟地址。

2)Do all programs have the same virtual addresses(that are eventually mapped to different physical addresses?)

在大多数系统中,程序的每个 运行 都会产生相同的逻辑地址布局。作为一种安全措施,这种情况越来越普遍。每次加载程序时,它都会以不同的方式加载。