自我修养——静态链接

版权声明:免责声明: 本人在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系 .挖井挑水无水表,不会网购无快递 https://blog.csdn.net/jscese/article/details/78320636

半年没更新博客了,一是工作内容变了,二是项目忙,其实就是懒 - - ||

这是第100篇了,不知不觉,点点滴滴,虽不说都是高质量博文,但也算是个里程碑,毕竟都是一手敲出来的文章

最近有点迷茫,脱离android大半年了,发张方向是个迷,程序员生涯接下来的路应该怎么走~ 得好好想想了

空下来 把之前的补上,程序员的自我修养 这本书里面的第三部分

撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/78320636本文来自 【jscese】的博客!

简单理解

静态链接就是将前面编译好的小.o 按照一定的规则组装到一起,形成一个大的可执行文件EIF


空间和地址分配

组装的规则是所有.o中相同段放到一起,在前文自我修养——目标文件.o有什么,有列出.o文件中的结构,组装规则如下:
这里写图片描述

除了bss段都是占用实际存储空间的
同时链接时会为目标.o中的每段分配虚拟地址

使用 :

objdump -h XX.o

查看段属性,其中的 VMA即为分配的虚拟地址,linux EIF默认虚拟地址从 0x08048000 开始


重定位

多个文件编程中,常用到的是引用其它文件的 函数以及变量,这些引用的函数以及变量在当前文件编译时,找不到具体地址,会先用0或者其它特殊地址代替
并且将此类符号 加入 到 重定位表

可通过如下命令查看.o中需要宠地位的符号:

objdump -r xx.o

在第一步虚拟地址分配之后,重定位步骤时,就会修正text段中的地址为具体的虚拟地址以及操作指令


强弱符号

代码中的函数以及初始化了的全局变量 - 强符号
为初始化的全局变量 -弱符号 (attribute((week/werkref))修饰可以强行设定为弱符号)

链接规则:
1:不允许重复定义强符号
2:强弱共存,选择强符号
3:弱弱共存,选择占用空间大的弱符号

未初始化的全局变量在编译时放在了common段,而不是放在bss段,原因是,需要在链接的时候,根据以上链接规则来决议弱符号的大小,在这之前不知道在bss段中应该定义多大的空间,只有在链接完成时才会将这个全局变量放到bss段中


静态库链接

用的最多的应该是标准C库了,常见libc.a
包含了很多实用的库函数以及功能函数,可用ar 命令查看库中包含的.o

ar -t libc.a

在使用这样的静态库时,也就是同上面一样,在链接的时候,顺藤摸瓜的找到调用的api函数,把该调用函数相关联的所有函数和变量都加载到我们的目标EIF所对应的段中,形成一个可执行完整逻辑的目标文件

有个ABI(application binary interface)的概念,类似于熟知的API,只不过更加深入层次一些,API界定的是函数,ABI界定的是二进制文件中的段的分布格式,地址计算方式,以及符号规则等,能够让链接器 统一识别的一种接口

详细的描述在书中~这里只是简单记录一下

猜你喜欢

转载自blog.csdn.net/jscese/article/details/78320636