静态链接

2.1 被隐藏了的过程
hello world
实际上,上述过程可分解为4个步骤,分别是预处理(prepressing)、编译(compilation)、汇编(assembly)和链接(linking):
这里写图片描述
2.1.1预编译
这里写图片描述
也已经被插入到.i文件中。所以当我们无法判断宏定义是否正确或头文件是否正确时,可以直接查看预编译后的文件来确定问题。
2.1.2编译
这里写图片描述
2.1.3汇编
这里写图片描述
2.1.4链接
这里写图片描述
2.2编译器做了什么
高级语言使得程序员们能够更加关注程序逻辑的本身,而尽量少考虑计算机本身的限制。
编译一般分为6步:扫描、语法分析、语义分析、源代码优化、代码生成和目标代码优化。整个过程如下图所示:
这里写图片描述
比如有一行c代码如下:
array[index]=(index+4)*(2+6)
CompilerExpression.c
2.2.1 词法分析
2.2.2语法分析
2.2.3语义分析
2.2.4中间语言生成
2.2.5目标代码生成与优化
2.3链接器的年龄比编译器长
原始的链接概念远在高级语言发明之前就存在了。程序被修改后,它可能会经常被修改,那么跳转指令后的地址就需要修改,这种重新计算各个目标的地址过程被叫做重定位。如果是多条纸带的程序,程序之间可能会有类似跨纸带之间的跳转,这种程序经常修改导致跳转目标地址变化在程序拥有多个模块的时候更为严重。
发明了汇编语言,可以使用符号标记位置。
人们开始将代码按照功能或性质划分,分别形成不同的功能模块,不同的模块之间按照层次结构或其他结构来组织。比如,c语言中,最小的单位是变量和函数,若干个变量和函数组成一个模块,存放在一个“.c”的源代码文件里,然后这些源代码按照目录结构来组织。在比较高级的语言中,如java中,每个类是一个基本的模块,若干个类模块组成一个包,若干个包组成一个程序。
代码模块化容易阅读、理解、重用,每个模块可以单独开发、编译、预测,改变部分代码不需要编译整个程序等。
模块之间最后如何形成一个单一的程序。可以归结为模块之间如何通信的问题,最常见的属于静态语言的C/C++模块之间通信有两种方式,函数调用和变量访问都可以归结为一种方式,那就是模块间符号的引用。模块间符号通信类似于排图版,定义符号的模块多一块区域,引用该符号的模块刚好少了那一块区域,两者刚好完美组合。这个模块的拼接过程就是本书的一个主题:链接(linking)。
这里写图片描述
这种基于符号的模块化的一个直接结果是链接过程在整个程序开发过程中变得十分突出。
2.4模块拼装–静态链接

人们把每个源代码模块独立地编译,然后按照需要将它们“组装”起来,这个组装的过程就是链接(linking)。链接器所要做的工作其实跟前面所描述的“程序员人工调整地址”本质上没什么两样,只不过现代的高级语言的诸多特性和功能,使得编译器、链接器更为复杂,功能更为强大,但从原理上来讲,它的工作无非就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配(address and storage allocation)、符号决议(symbol resolution)和重定位(relocation)等这些步骤。
符号决议有时候也被叫做符号绑定、名称绑定、名称决议,甚至还有叫做地址绑定、指令绑定的,大体上它们的意思都一样,但从细节角度来区分,它们之间还是存在一定区别的,比如”决议”更倾向于静态链接,而“绑定”更倾向于动态链接,即它们所使用的范围不一样。在静态链接,我们将统一称为符号决议。
最基本的静态链接过程如图所示,每个模块的源代码文件经过编译器编译成目标文件,目标文件和库一起链接形成最终可执行文件。而最常见的库就是运行时库,它是支持程序运行的基本函数的集合。库其实是一组目标文件的包,就是一些最常用的代码编译成目标文件后打包存放。
后文内容都将称object文件为目标文件,很多时候我们也把目标文件称为模块。
main.c调用foo函数,暂时把这些调用foo的指令的目标地址搁置,等待最后链接的时候由链接器区将这些指令的目标地址修正。链接前如果使用了某目标文件里的变量,可先将目标地址置0。链接时,会把这个地址进行修正。每个要被修正的地方叫一个重定位入口。重定位所做的就是给程序中每个这样的绝对地址引用的位置“打补丁”,使他们指向正确的地址。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值