程序员的自我修养——链接,装载与库(四)静态链接

  • 链接器在链接过程中将多个目标文件加工合并为一个文件。
  • 层序链接:将多个目标文件安装次序叠加起来。但是这样会导致空间的浪费,产生大量的内部碎片。
  • 相似段拟合:将相同性质段合并在一起。这个也是最实际的方法。
  • 链接器合并各个段,也将.bss段进行合并,为目标文件分配地址空间(虚拟地址空间)
  • 链接器进行链接时才用相似段拟合的方法,整个链接过程分为两步:第一 空间与地址的分配(链接器获得所有目标文件的长度,采用相似段拟合方法进行合并,然后建立映射)。第二 符号解析与重定位(进行符号的解析和重定位,调整代码中的地址)。
  • 链接前会所使用的地址是虚拟地址。
  • 重定位表用来保存与重定位相关的信息。每个要被重定位的ELF段有一个对应的重定位表(重定位段)。
  • 每个要被重定位的地方叫重定位入口,重定位的入口的偏移表示该入口在要被重定位的段中的位置。
  • 链接过程可以将我们目标文件中使用的符号可以被其他的目标文件使用并且进行定义。
  • 链接器对目标文件扫描完后,目标文件中未定义的符号都应该在全局符号表中(ELF的辅助段)。
  • 绝对寻址修正和相对寻址地址的修正的区别就是绝对寻址修正后的地址为该符号的实际地址。相对寻址修正后的地址为符号距离被修正位置的地址差。
  • 编译器将将编译单元,编译成目标文件时,未初始化的全局变量的内存地址的大小是未知的。
  • C++的编译器在很多时候会产生代码重复的代码,模板就非常典型(实质就是宏)。代码重复会造成空间浪费,地址较易出错,指令运行效率较低。使用函数级别链接(将每个函数都保存在一个段里面,等使用的时候就链接到输入文件,其他的可以以抛弃)的技术可以解决这个问题。
  • main函数执行之前,要先初始化进程的执行环境。全局对象的构造函数在main函数之前被执行,全局对象的析构函数在main函数之后被执行。linux下的程序的入口函数是_start。
  • .init段 保存的是可执行代码的执行指令,它构成了进程的初始化代码,main函数之前被执行。
  • .fini段 保存进程终止代码的指令。main函数之后被执行。
  • API:应用程序接口  ABI:源代码级别的接口(二进制层面的接口)。
  • 语言的开发环境会带有语言库。这些库就是对操作系统API的封装。
  • 静态库是一组目标文件的集合。
  • 链接器链接静态库时是以目标文件为单位的。
  • 静态库中每个函数被独立的放在一个目标文件中可以尽量的减少空间的浪费。(因为链接的时候可能会附带有那些用不到的函数,会占内存空间)。
  • 操作系统内核总本质上将也是一个程序。 
  • linux下的可执行文件的格式是ELF,windows下的可执行文件的格式是PE。而这两中格式都是由COFF格式发展而来的。
  • COFF文件的结构基本与ELF文件相似。COFF文件的文件头包括了两部分:描述文件的总体结构与属性的映像头。
  • 段所拥有的属性包括段名,物理地址,虚拟地址,原始数据大小,段在文件中的位置,该段的重定位表在文件中的位置,该段的行号表在文件中的位置。
发布了78 篇原创文章 · 获赞 11 · 访问量 5072

猜你喜欢

转载自blog.csdn.net/qq_43145594/article/details/104252985