链接器
1.什么是链接器
链接器就是将单独编译后的各个目标文件组合起来,形成单个可执行程序的过程。
2.链接器的任务
a. 搜索程序库,找到被本程序调用的库函数;
b. 分配每个模块代码的内存位置,并且调整绝对引用实现指令的重定位;
c. 实现文件之间的引用。
第一个任务是为了保证程序中的所有标记都被事先定义好。链接器匹配全局符号和各个文件中的未解析引用(unresolved reference),使得所有全局标记都能引用。
当确定所有的标记都可以引用之后,链接器接下来分配每个模块所占用的内存。当链接器将一个模块换入内存,所有相关的引用都必须重定位以确保映射正确。因为链接器知道所有的重定位信息,所以能确定所有的引用的位置,从而能够有效地找到并回补这些引用。
最终生成一个可执行文件。可执行文件的格式基本与目标文件相似,唯一的差别在于它包含了所有的引用和重定位信息。如下图所示:
程序的装载
在运行前,可执行程序是以文件的形式存储在诸如磁盘的二级存储设备中的。在UNIX操作系统上,操作系统内核将程序装入内存后就可以运行。开始执行之前,操作系统执行以下步骤:
1)读取可执行文件头,得到正文段(也称代码段)和数据段的大小;
2)为该程序创建新的地址空间。这个地址空间要足够大,用于装入正文段和数据段内容,同时还要建立一个堆栈段。内存布局如下图所示:
3)将指令和数据从可执行文件复制到新创建的地址空间中。
4)将程序参数复制到堆栈段。
5)初始化机器的寄存器。通常情况下,多数寄存器是清空的,但堆栈指针(寄存器)必须设置为指向堆栈段的栈顶地址。
6)转移到起始程序段。起始程序段将程序在堆栈中的内容拷贝到寄存器中去,并且调用其中的main例程。当main例程结束时,该起始程序还要调用系统退出命令,结束整个程序的执行。