主的任务罢了
一.代码产生到可以运行经历了以下三个阶段:
1·编译:编译器通过一系列分析,将代码翻译成为汇编语言,再将汇编语言翻译成为机器语言,最后生成可以定位的二进制目标文件
2.链接:解决符号之间的重定位问题
3.装载:将可执行文件(.exe)加载到内存
二.编译(源文件(.c)→二进制文件)
共分为三步:1.对源文件(.c)进行预处理:处理一些#定义的命令或语句(eg.#include,#ifdel等等),将源代码.c文件生成预处理(*.i)文件
2.编译:进行词法分析、语法分析和语义分析等,将预处理文件生成*.s的汇编文件;
3.汇编:汇编指令翻译成为机器指令,生成可以重定位的二进制文件(.o)(又叫作目标文件)
这里借用了知乎大佬的图,链接为:你似乎来到了没有知识存在的荒原 - 知乎
#目标文件分类
1.可重定位的目标文件(.o):包含二进制代码与数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件
2.可执行目标文件:包含二进制代码与数据,其形式可以被复制到内存并执行
3.共享目标文件:一种特殊类型的可重定位目标文件,可以在加载或者运行时被动态的加载进内存并链接
#解析可重定位目标文件
ELF
编译结束后进行链接。
三.链接(静态链接与动态链接)
1.静态链接(在装载之前,完成所有符号的引用)
静态链接:链接器在链接阶段将各种库文件和相关文件集成到可执行文件中,在windows下静态链接库以.lib结尾,linux下以.a结尾
步骤:1,空间与地址的分配,扫描所有的目标文件,合并相似段,收集当中所有的符号信息,
2,符号解析与重定位,调整代码位置
优点:程序发布时无需带库,可以独立执行
缺点:1,浪费内存空间,多进程操作系统下,内存中可能会存在多个相同的库
2,程序开发受限,有一个模块更新,要重新编译打包整个代码
2.动态链接(在运行时才进行符号重定位)
动态链接:动态链接是把链接过程在运行时进行,动态链接在可执行文件装载或运行的时候,由操作系统的装载程序加载库文件,windows下以.dll结尾,也有.lib的,但是这个是叫做导入库,和静态链接的不一样,linux下以.so结尾。。
步骤:编译时通过记录一系列符号与参数,在程序运行或加载时将这些信息传给操作系统,操作系统将需要的动态库加载到内存中去,然后再程序运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。
四,静态链接库与静态链接库
采用静态链接方式实现链接操作的库文件称为静态链接库;采用动态链接方式实现链接操作的库文件称为动态链接库
在 Linux 发行版系统中,静态链接库文件的后缀名通常用 .a 表示,动态链接库的后缀名通常用 .so 表示;在 Windows 系统中,静态链接库文件的后缀名为 .lib,动态链接库的后缀名为 .dll。
#静态链接库
win平台下xxx.lib文件即为静态链接库。静态库只有lib文件,该文件包含了函数代码本身,在编译时直接将代码完整添加到程序之中。
#动态链接库
win平台有三个核心动态链接库:
1,kernel32.dll:32位动态链接库文件,属于内核级文件。负责控制系统中的内存管理,数据的输入输出和中断处理。
2,user32.dll:是用户界面相关应用程序接口,用于包括Windows处理,基本用户界面特性
3,gdi32.dll:图形用户界面相关程序,包含的函数用来绘制图像和显示文字