深入理解计算机系统之链接
在学习《深入理解计算机系统》学到链接的时候,关于课上内容以及代码实践加上自己理解,整理了以下内容。
首先,一个C语言程序,会经过预处理,编译,汇编,链接最终形成一个可执行的目标文件。
而链接器的主要任务就是:
-
符号解析:将每个符号引用正好和一个符号定义关联起来(全局量即为符号,如全局变量,静态变量和函数)
-
重定位:即是将符号与一个内存位置关联起来,即在一块连续的虚拟地址空间内,为符号重新分配了地址,即重定位(合并.o文件,确定每个符号的地址,在指令上填入新的地址,详细区别下文讲解)
而目标文件有三种形式,分别是:
-
可重定位目标文件
-
可执行目标文件
-
共享目标文件
这三者的区别是:
- 可重定位目标文件(.o文件):包含二进制代码和数据,是由一个.c文件经过预处理,编译,汇编得到的。
(main.c --预处理器(cpp)–>main.i --编译器(ccl) -->main.s —>汇编器(as)—>main.o —>连接器(ld)—> main)
此次实验是以ELF可重定位目标文件为例。(如下所示)
特别提出的是.bss和COMMON节的区别:
(1): .bss中存放的是未初始化的全局和静态C变量以及所有被初始化为0的全局或静态变量,未初始化的默认为0
(2): COMMON节中存放的数据则是不会给予默认值,假如是未初始化的指针符号,则会放在COMMON节而不是bss节
- 可执行目标文件(.out文件):包含二进制代码和数据,可以被直接复制到内存并执行。即由.o文件经过链接后形成的文件。可以在ubantu终端输入指令 gcc -Og -o fun main.c sum.c (-Og代表可调试,-o 后面跟程序名)
- 共享目标