Linux----编译链接原理

通过gcc编译程序,在执行程序的时候需要4个步骤:预处理、编译、汇编和链接

前三个可统称为编译过程,编译过程都是单文件单独编译,每个.c文件编译后都有一个对应的.o文件

1.预编译

gcc   -E  源文件   -o   要生成的目标文件名(**.i)

(1)删除注释

(2)宏替换

(3)处理“#include”等预编译指令

2.编译

gcc   -S   **.i                  默认生成一个**.s

3.汇编

gcc   -c    **.s                 默认生成一个**.o,可重定位的二进制目标文件

.o是二进制文件,要用objdump查看

C语言的只有数据和函数名会生成符号

.bss中存的是没有初始化的静态变量 和 初始化为0的变量。

中间文件的ELF格式 :.o文件(.bss不在ELF文件中,.bss---->best save space 节省磁盘空间,不占内存)

4.链接

gcc    **.o                       默认生成一个a.out文件,可执行文件

gcc    **.o   -o      指定可执行文件名

(1)合并各个段:合并各个相同的段,并调整各个段的大小和起始位置

相同名字的段放到一块,还要将相同属性的段合并到一块。

(2)合并符号表:

若两个函数中有两个名字相同的全局变量,一个初始化,可认为强符号,一个未初始化,可认为弱符号。在合并符号表时,会用强符号代替弱符号,或者说只保留了强符号。

若为两个弱符号,则不会出现符号重定义;

若是两个强符号,则会出现符号重定义。

(3)进行符号解析:所有中间文件对符号引用的地方都要找到符号定义的地方,给符号分配虚拟地址

可执行文件的ELF格式:磁盘上存储

C进程4G的虚拟地址空间(.bss是占进程空间的)

(4)符号重定位----链接阶段最重要的地方

在.text中所有使用符号的地方,都要替换成符号的虚拟地址。

所有引用数据的地方,则替换成其数据符号的虚拟地址。

所有引用函数的地方,则替换函数符号地址相对于下一行指令的偏移值。
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值