news 2026/4/18 12:59:07

对《深入理解计算机系统》第七章 链接的读书随笔

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
对《深入理解计算机系统》第七章 链接的读书随笔

对《深入理解计算机系统》第七章“链接”的学习随笔

学习《深入理解计算机系统》第七章“链接”后,我对程序从代码到可执行文件的最后一步关键流程有了清晰认知。链接本质上是由链接器负责,将多个独立的代码段、数据段组合成一个可加载、可执行单元文件的过程,是构造大型程序不可或缺的环节。

理解链接的核心意义,不仅能帮助我们高效构建大型程序(将程序拆分多个模块独立开发、协同整合),更能帮助我们规避编程中的危险错误,搞清楚程序中作用域规则的底层实现逻辑,掌握符号、库等核心概念,进而灵活运用共享库优化程序性能、节省资源。

链接构建可执行文件的核心流程分为两步:符号解析与重定位。符号解析的核心是“找到对应关系”,即明确每个模块所引用的符号(如函数、全局变量)的具体定义,确定符号的类型及所属文件,确保引用的符号都有唯一且合法的定义;符号解析完成后,进入重定位阶段,通俗来讲,就是确定所有解析后的符号、代码段、数据段在最终内存中的具体位置,将符号引用与实际内存资源建立精准关联,让程序能够正确找到所需的指令和数据。

一、目标文件的分类与结构

链接过程中涉及三种核心目标文件,用途不同但文件格式高度一致:

  1. 可重定位文件:即静态库的组成单元,用于后续链接生成可执行文件或共享目标文件;

  2. 可执行文件:链接的最终产物,可直接被操作系统加载运行;

  3. 共享目标文件:即动态库,可在程序运行时被动态加载,供多个程序共享使用。

无论哪种目标文件,均包含以下关键节(段),各司其职:

  • 代码段:存放编译后的机器指令,是程序执行的核心;

  • 只读段:存放常量等不可修改的数据;

  • 初始化数据段:存放已初始化的全局变量和静态变量;

  • 未初始化数据段:存放未初始化的全局变量和静态变量(程序加载时会被初始化为0);

  • 符号表:记录模块中定义和引用的函数、全局变量信息,是符号解析的核心依据;

  • 重定位表:包含代码段、数据段中需要重定位的符号引用信息,告知链接器如何修改这些引用;

  • 调试表:存放局部变量、类型定义、全局变量详情及源文件相关信息,用于程序调试;

  • 行号映射表:建立源文件行号与机器指令的对应关系,方便调试时定位代码;

  • 字符串表:存储符号名、文件名等字符串,避免重复存储,节省空间。

二、符号表与符号解析

(一)符号表的三种符号类型

  1. 可输出的全局符号:本模块定义,供其他模块引用(如全局函数、非静态全局变量);

  2. 被输入的全局符号:本模块引用,但由其他模块定义的符号(如调用其他文件的函数);

  3. 无法输出的局部符号:仅在本模块内部可见,不可被其他模块引用(如静态函数、静态变量)。

(二)符号解析规则

符号解析的核心是为每个符号引用找到唯一的符号定义,其中局部符号遵循“唯一定义”原则,一个模块内不可出现同名局部符号;全局符号的解析由链接器负责,为解决全局符号多重定义问题,链接器遵循以下三条核心规则:

  1. 禁止多个同名强符号(已初始化的全局变量、函数)共存,否则链接报错;

  2. 若存在一个强符号和多个同名弱符号(未初始化的全局变量),优先选择强符号作为最终定义;

  3. 若存在多个同名弱符号,链接器可任意选择其中一个作为最终定义。

三、静态库及其链接过程

静态库是多个可重定位目标文件的归档集合,其核心价值在于“模块化整合、按需引用”——将多个相关函数模块整合为一个库文件,链接时无需加载整个库,仅提取程序所需的模块,避免冗余代码,节省磁盘空间。

链接器使用静态库的核心流程,围绕三个关键集合展开(已合成文件集合E、未解析符号集合U、已定义符号集合D):

  1. 链接器先遍历命令行中的所有文件,区分目标文件和静态库归档文件;

  2. 对于目标文件,直接将其加入E集合,同时更新U集合(新增该文件的未解析符号)和D集合(新增该文件的已定义符号);

  3. 对于静态库,仅提取其中能解析U集合中未解析符号的模块,将这些模块加入E集合,并更新U和D集合;未被引用的模块不会被加载,实现“按需引用”。

四、重定位的核心流程与细节

当符号解析完成、所有符号的定义均已确定后,链接器进入重定位阶段。此时链接器已明确所有输入模块的大小和排列顺序,核心任务是确定每个符号的最终内存地址,并修正所有符号引用,具体分为两步:

  1. 节合并:将所有输入模块中相同类型的节(如所有代码段、所有初始化数据段)分别聚合,形成可执行文件的对应节,确定每个节的起始内存地址;

  2. 符号引用修正:遍历每个节中的重定位条目,按照条目指示的规则,修改代码或数据中的符号引用,使其指向节合并后的最终内存地址。

(一)重定位条目

由于编译器编译模块时,无法预知该模块最终会被加载到内存的哪个位置,也无法确定引用的外部符号的地址,因此会为每个需要重定位的符号引用生成一个“重定位条目”,用于告知链接器“该位置需要修改、修改的规则是什么”,是重定位过程的核心依据。

(二)重定位符号引用的两种类型

  1. 相对引用:符号引用的地址是相对于当前指令地址的偏移量,重定位时仅需根据节的最终地址调整偏移量,兼容性更强;

  2. 绝对引用:符号引用直接指向符号的最终内存地址,重定位时需将引用地址直接修改为符号的实际地址。

五、动态链接共享库(动态库)

动态库与静态库的核心区别在于“加载时机和共享机制”:静态库在链接时会被复制嵌入到可执行文件中,每个使用静态库的程序都会包含一份库代码,容易造成内存和磁盘冗余;而动态库不会在链接时嵌入可执行文件,仅在程序加载或运行时,由动态链接器加载到内存,供多个进程共享使用,极大节省了内存和磁盘资源。

此外,动态库的更新无需重新编译可执行文件,仅需替换动态库文件即可,提升了程序的维护效率,是现代程序开发中常用的库形式。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 2:59:53

(100分)- 单词倒序(Java JS Python)

(100分)- 单词倒序(Java & JS & Python)题目描述输入单行英文句子,里面包含英文字母,空格以及,.?三种标点符号,请将句子内每个单词进行倒序,并输出倒序后的语句。输入描述输入字符串S,…

作者头像 李华
网站建设 2026/3/12 13:34:20

小程序计算机毕设之基于springboot+小程序的高校生活互助平台小程序基于SpringBoot校园生活服务小程序(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/4/17 13:13:37

AI协作沟通不畅?计算机科学研究中AI应用架构师的3种解决方案

AI协作总卡壳?计算机科学研究中AI应用架构师的3个破局方案 一、引言:那些让研究团队“拍桌子”的瞬间 上周参加一个计算机视觉研究团队的周会,我亲眼目睹了一场“经典冲突”: 坐在左边的李研究员拍着论文草稿说:“我要的是**‘小样本情况下目标特征的跨域一致性’**——…

作者头像 李华
网站建设 2026/4/18 0:26:59

基于Java和Vue开发的同城顺风车拼车约车叫车打车系统

博主介绍: 所有项目都配有从入门到精通的安装教程,可二开,提供核心代码讲解,项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频; 项目的界面和功能都可以定制,包安装运行&#xf…

作者头像 李华
网站建设 2026/4/18 0:25:17

例说FPGA:可直接用于工程项目的第一手经验【3.3】

第15章 工程实例13——基于VGA显示器的720p的广告机设计 本章导读 本章工程与第10章的电子点菜单有异曲同工之妙,只不过一个是将图像存储显示功能应用在了“点菜单”上,一个是将图像存储显示功能应用在了“广告机”上。 15.1 功能概述 本实例的基本架构和电子点菜单项目实…

作者头像 李华