程序预处理,编译,汇编,链接(静态库,链接库)详解

程序从原始文件到可执行文件过程

步骤原始程序预编译编译汇编链接
文件fun.cpp、fun.hfun.ufun.sfun.ofun.exe

预编译

  • 展开头文件
  • 宏替换
  • 去掉注释
  • 条件编译(#ifdef 、#endif …)

编译

将代码转换为汇编代码以及1、编译器在每个文件中保存一个函数地址符表,该表保存着该文件中各函数的地址;2、在这步要生成汇编代码,调用函数的代码会被编译为一条call指令,call后面跟着jmp指令的汇编代码地址,jmp后面跟着的才是“被调用函数汇编成的汇编代码的第一条指令”的地址,给call指令后面补上地址是在链接的时候做的。(调用函数:call -> jmp->函数的第一条指令(链接时才补上地址))

汇编

将汇编转换为机器码

链接

编译器将多个.o文件链接到一起生成可执行程序.exe,在这个过程中将call指令后面的地址补上;方式是从当前文件的函数地址符表开始找、扎到填上,没找到再继续向别的文件地址符表找,如果找不到,则链接失败。

静态链接库(linux: .a \ win: .lib)

之所以称为 静 态 库 静态库 ,是因为在链接过程会将汇编生成的目标文件.o和引用用到的库一起链接打包到可执行文件中。因此对应的链接方式为静态链接。试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

  • 静态库对函数库的链接是在编译时期完成的
  • 程序运行时与函数库再无瓜葛,移植方便
  • 缺点:浪费空间和资源,因为相关的目标文件和牵扯的函数库被链接合成了一个可执行文件

动态链接库(linux: .so \ win : .dll)

1、静态链接库不可避免的会产生空间浪费(见下图)
2、此外,还有一个问题就是静态库对于程序的更新、部署和发布都会带来麻烦。如果静态库更新了,所有使用他的应用程序都要重新编译、发布给用户(对于用户而言可能只是一个小改动,却导致整个程序要重新下载)
在这里插入图片描述
而动态库在程序编译时并不会连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存中只需要一份该共享库的实例,避免了空间浪费的行为。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。
在这里插入图片描述
动态库的特点:

  • 动态库把对函数的链接过程推迟到程序运行的时期
  • 可以进行进程之间的资源共享
  • 程序升级变得简单
    缺点:使用动态链接库的应用程序不是自完备的,1、它依赖的DLL模块也要存在,如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;2、速度比静态链接慢。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件,统统死掉。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值