编译---链接过程

我们知道,.c文件是不能直接执行的,必须经过编译和链接阶段成为可执行文件才能够执行

那么从.c文件到可执行文件需要那些过程呢?????????????????????

首先我们来看编译阶段

其实编译阶段可以分为这几个阶段

 预编译阶段:编译阶段主要是做着几件事情:  删除注释,处理以#开头的一些预编译指令

此阶段结束后生成:.i文件。


 编译阶段 :编译阶段主要做这几件事情:语法语义的分析,代码的优化,汇总所有的符号

此阶段结束后生成:.s文件

 

汇编:汇编阶段主要做这几件事情:它会根据指令(mov,lea,add等)和机器平台的结合->把

把.s文件转化成机器码,构建.o/.obj文件的格式  ,此阶段完成后生成.o/.obj文件(二进制可重定位文件)

此后,生成符号表:每一个数据生成一个符号,一个函数只生成一个符号(函数名),此阶段完成后

文件是不可执行的,因为数据在使用的时候分配的是0内存(也就是说数据没有分配内存),所以就

有了下面的阶段


链接:

(1)合并所有obj文件的段:所有相同属性的段进行合并,组织在一个页面上(比如所有的.text(只读),所有

的.bss,.data(可读可写))

(2)调整段偏移和段长度:因为段进行了合并,所以必须调整偏移量和长度

(3)合并符号表,进行符号解析,分配内存地址:所有obj符号表中对符号引用的地方都要找到该符号的定义的地方,比如你在

文件a中定义了一个全局变量,在b文件中想去引用它,(链接过程所有的文件是一起链接了),而合并符号表就

实现了这一功能;分配内存地址(数据分配绝对地址,而函数分配下一行指令地址的偏移量)

(4)符号的重定位:把之前没有正确的符号地址改正成正确的地址,只对所有obj文件的globle符号进行处理,Local文件不做处理

——————————————————————————————————————————————————————————

这最终才是我们的可执行文件

接下来我们来看一下.o文件内容的布局:

main.o


我们会发现在文件上的布局少了在虚拟用户地址空间里的.bss,这是因为什么呢,这是因为在.bss存储的数据都属未初始化或初始化为

0的数据,完全没有必要现在占用我问文件的存储量,从这里也可以看出,.bss不占用文件的内存,那么,我们的.bss里面的数据到底在

哪里呢,大家有没有注意到最后一个名字:section table:在ELFHeader中存放着它的地址,它就是段表:保存文件所有段的详细信息,

读文件头时就可知道,所以也知道.bss里面的信息了

————————————————————————————————————————————————————————————-

我们再来看一下可执行文件的组成格式


其中program headers中存放这两个load;知名当前可执行文件哪些段可放在一个页面上

而这两个load 存放在磁盘上

————————————————————————————————————————————————————————————

程序的运行         进程

1:创建虚拟地址空间到物理内存的映射(创建内核地址映射结构体,创建页目录和页表)

2:加载代码段和数据段

3:把可执行文件的入口地址(main的地址)写到cpu的pc寄存器里面




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值