完整教程:【Linux】Linux下的静态链接的底层逻辑

news/2025/10/13 14:15:09/文章来源:https://www.cnblogs.com/yxysuanfa/p/19138379

前言:欢迎各位光临本博客,这里小编带你直接手撕**,文章并不复杂,愿诸君**耐其心性,忘却杂尘,道有所长!!!!

在这里插入图片描述


IF’Maxue:个人主页

  个人专栏:
《C语言》
《C++深度学习》
《Linux》
《数据结构》
《数学建模》

⛺️生活是默默的坚持,毅力是永久的享受。不破不立!

文章目录

      • 静态链接与动态链接原理详解
        • 1. **目标文件:代码的“零件包”**
        • 2. **链接过程:合并零件包,解决“地址谜题”**
        • 3. **地址重定位:磁盘上的“虚拟地图”**
        • 4. **动态链接:共享库的魔法**
        • 总结

这是一篇博客的雏形,请用通俗化的语言结合图片内容和上下文,不要修改减少或增添所有的图片,以图片为中心上下文内容要强关联,对其进行优化,
要求:通俗化,简洁化,分段式,详细化,结合代码

静态链接与动态链接原理详解

大家好!今天我们来聊聊程序编译和链接的那些事儿。想象一下,写代码就像拼乐高:源代码是零件,编译器是组装工,链接器就是最终拼接大师。静态链接和动态链接是两种拼接方式,我会用通俗语言、结合图片和代码,一步步带你搞懂核心原理。所有图片都来自真实案例,我会以它们为中心,详细解释上下文。


1. 目标文件:代码的“零件包”

当我们写C程序时,比如hello.ccode.c,编译器会先把它们变成目标文件(.o文件)。这些文件就像未组装的乐高零件包,里面包含代码和数据,但还没合并。

关键点


2. 链接过程:合并零件包,解决“地址谜题”

链接器的作用是把多个.o文件(如hello.ocode.o)拼成一个可执行程序。这就像把乐高零件包拆开,按图纸组装。合并后,所有代码和数据节统一编址,解决未定义符号的问题。

  • 合并目标文件
    链接过程
    链接器将多个.o文件的Text和Data节合并成一个。例如,hello.o的Text节和code.o的Data节拼接,形成新结构。原本独立的节(如.text.data)被重新编号(如图中Section 14)。

  • 工具objdump:看内部机器码
    objdump -d反汇编目标文件,能看机器指令:
    objdump输出
    这里,call指令的地址是00 00 00 00(全0),因为函数地址还没确定。链接后,这些空白被真实地址填充。

结合代码示例
假设hello.c调用printfcode.c定义全局变量。编译后汇编如下:

// hello.c(简化版)
extern int global_var;
void hello() {
printf("Value: %d\n", global_var); // 调用外部函数和变量
}

编译成汇编(hello.s):

; hello.s 片段
call printf   ; 机器码 e8 00 00 00 00(地址未填充)

hello.c vs hello.s
call指令的机器码是e8,后跟4字节地址。链接前是0,因为模块未合并。


3. 地址重定位:磁盘上的“虚拟地图”

链接后,可执行程序在磁盘上就有完整地址了,这叫地址重定位。它基于虚拟地址空间——程序运行时“看到”的内存地图,不是真实物理地址。

  • 填充地址空白
    地址重定位
    链接器计算每个符号的偏移量。例如,printf函数在合并Text节中的位置是0x400500,就填充到call指令后。公式简单:地址=基址+偏移量地址 = 基址 + 偏移量地址=基址+偏移量

  • 虚拟地址空间:平坦模式
    虚拟地址空间
    可执行程序在磁盘上使用虚拟地址编址(如从0x400000开始)。Text节放代码,Data节放变量,BSS节放未初始化数据。这种“平坦模式”让程序加载到内存时,地址直接映射,无需大调整。

关键点

  • 磁盘上的地址叫逻辑地址,内存中叫虚拟地址,物理地址是RAM真实位置。
  • 入口地址(如_start)是程序起点,加载时CPU的EIP寄存器指向它。
    入口函数_start

4. 动态链接:共享库的魔法

动态链接(共享库)让多个程序共用同一份代码,节省内存。不同于静态链接(库代码复制到每个程序),动态库加载到内存共享区。

  • 进程如何看待动态库
    动态库关联
    进程虚拟地址空间包含共享区(如libc.so)。调用库函数时,CPU跳转到共享区执行,完成后返回。
    mm_struct
    操作系统用mm_struct管理虚拟内存,库代码通过页表映射到共享区。

  • 优势:代码不重复
    动态库代码
    动态库(如.so文件)在磁盘只有一份,所有进程共享内存中的副本。例如,100个程序用printf,内存中只存一份libc代码。

对比静态链接

  • 静态库:每个程序自带库副本,文件大、内存占用高。
  • 动态库:轻量灵活,但首次调用稍慢(需加载库)。

总结

静态链接像“打包行李”:所有代码合并成一个文件,独立但笨重。动态链接像“共享单车”:代码在内存中共用,高效灵活。关键步骤记三点:

  1. 编译生成.o文件(零件包)。
  2. 链接合并并解决地址(拼装地图)。
  3. 运行时加载到虚拟地址空间(执行地图)。

通过图片和代码,希望你对链接过程有了直观理解。下次遇到“undefined reference”错误,就知道是链接器在喊:“嘿,我找不到那个零件!”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/936133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年10月通风气楼厂家最新推荐排行榜,屋顶通风气楼,工业厂房通风气楼,节能环保通风气楼公司推荐!

2025年10月通风气楼厂家最新推荐排行榜:屋顶通风气楼,工业厂房通风气楼,节能环保通风气楼公司推荐!随着工业和建筑行业的快速发展,通风气楼在各类建筑中的应用越来越广泛。屋顶通风气楼、工业厂房通风气楼以及节能…

10/13

今天满课,全是专业课,好累

CF1882E1 Two Permutations (Easy Version)

题目大意: 有两个排列,长度分别为 \(n,m\),每次你可以选择两个整数 \(1 \le i \le n, 1 \le j \le m\),并交换 \(p_{1} \sim p_{i - 1}\) 和 \(p_{i + 1} \sim p_{n}\) 两个整体,\(q,j\) 同理。 请构造出一种不超…

2025年10月实验室净化订做厂家最新推荐排行榜,专业定制与高效服务口碑之选

2025年10月实验室净化订做厂家最新推荐排行榜,专业定制与高效服务口碑之选随着科技的不断进步和实验室环境要求的不断提高,实验室净化工程的需求日益增长。为了帮助筛选实验室净化品牌,特此发布权威推荐榜单,为采购…

20234320 2025-2026-1 《网络与系统攻防技术》实验一实验报告

20234320 2025-2026-1 《网络与系统攻防技术》实验一实验报告 1.实验内容 1.1 目标任务 a.对目标pwn文件,手工修改可执行文件从而改变执行过程,跳转到getShell得到可用Shell b.对目标pwn文件,利用foo函数的Bof漏洞,…

2025年10月清洗机厂家最新推荐排行榜,高压清洗机,超声波清洗机,工业清洗机,商用清洗机公司推荐!

2025年10月清洗机厂家最新推荐排行榜:高压清洗机、超声波清洗机、工业清洗机、商用清洗机公司推荐随着工业和商业领域的不断发展,清洗机的需求日益增加。无论是高压清洗机、超声波清洗机,还是工业清洗机和商用清洗机…

2025年10月上海殡葬服务一条龙最新权威推荐榜:专业贴心的全程陪伴与优质服务厂家选择指南

2025年10月上海殡葬服务一条龙最新权威推荐榜:专业贴心的全程陪伴与优质服务厂家选择指南引言随着社会的发展和人们生活水平的提高,对于殡葬服务的需求也日益增长。上海作为中国的一线城市,其殡葬服务行业更是备受关…

JavaScript链式调用(基础篇)

JavaScript链式调用(基础篇)Posted on 2025-10-13 14:00 lzhdim 阅读(0) 评论(0) 收藏 举报一、什么是链式调用?链式调用(Method Chaining) 是一种让多个方法通过连续的“点操作符”调用的编码风格 // 示例:…

【服务器知识】HTTP 请求头信息及其用途详细说明 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[GenAI] 大模型微调

英文:Fine-tuning 中文:大模型微调 大模型的构建其实分为 2 个阶段:预训练(pre-training):此阶段模型会在 大规模、多样化的数据集 上进行训练,从而形成全面的语言理解能力。 微调(fine-tuning):在规模较小的…

2025年10月气柱袋厂家最新推荐排行榜,缓冲包装气柱袋,防震气柱袋,充气气柱袋公司推荐!

2025年10月气柱袋厂家最新推荐排行榜:缓冲包装气柱袋、防震气柱袋、充气气柱袋公司推荐随着物流和电子商务行业的快速发展,气柱袋作为一种高效的缓冲包装材料,越来越受到企业的青睐。为了帮助企业筛选优质的气柱袋品…

[GenAI] LoRA微调

LoRA 英文全称为 Low-Rank Adaptation,中文:“低秩适配器” 秩的概念 英文 Rank 中文:秩 所谓秩,指的就是一个矩阵中 真正包含的信息量 有多少。 🙋小红买了 3 个苹果 4 个桃子,花了 18 元,小明买了 2 个苹果 …

2025年10月保洁公司最新权威推荐榜:专业清洁与高效服务的品质之选

2025年10月保洁公司最新权威推荐榜:专业清洁与高效服务的品质之选随着城市化进程的加快和人们生活水平的提高,对清洁服务的需求日益增长。保洁公司在保障环境卫生、提升生活品质方面发挥着重要作用。为了帮助筛选保洁…

2025年10月粉末涂料厂家最新推荐排行榜,环氧粉末涂料,聚酯粉末涂料,丙烯酸粉末涂料,耐候性粉末涂料公司推荐

2025年10月粉末涂料厂家最新推荐排行榜:环氧、聚酯、丙烯酸及耐候性粉末涂料公司推荐随着工业和建筑行业的快速发展,粉末涂料因其环保、高效、耐用等优点,逐渐成为涂料市场的主流选择。为了帮助筛选粉末涂料品牌,特…

基于单片机的汽车防碰撞刹车系统(论文+源码) - 实践

基于单片机的汽车防碰撞刹车系统(论文+源码) - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

git submodule

配置子模块: 子模块A:libA.git 子模块B:libB.git 主仓库:super.git添加子模块A: git submodule add ../libA.git lib/lib_a添加子模块B: git submodule add ../libB.git lib/lib_b

2025年10月确有专长培训机构最新推荐榜单:专业课程与高通过率口碑之选

2025年10月确有专长培训机构最新推荐榜单:专业课程与高通过率口碑之选随着社会对专业技能需求的不断增长,确有专长培训行业也迎来了前所未有的发展机遇。各大培训机构纷纷推出各类课程,以满足不同人群的需求。然而,…

有源探头DC与RMS参数详解:选型与应用指南

本文解析了有源电压探头的DC和RMS参数,指出其在测量直流和交流信号中的关键作用,并强调两者在峰值耐压能力上的等价性。在有源电压探头的技术参数中,DC(直流)和RMS(有效值)是两个至关重要的指标。正确理解这两个…

Objective-C Runtime 中的关联对象(Associated Object)方法

objc_setAssociatedObject(phoneLbl, @"phoneNumberKey", salesmanPhoneNum, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 使用场景 常用于给系统类(如 UIView、UILabel 等)动态添加自定义数据,特别是在分类(Ca…

2025年10月无锡公考培训机构最新权威推荐榜单:专业师资与高通过率口碑之选

2025年10月无锡公考培训机构最新权威推荐榜单:专业师资与高通过率口碑之选随着公务员考试的热度持续上升,越来越多的考生选择参加公考培训以提高自己的竞争力。在无锡这样一个竞争激烈的市场中,如何选择一家合适的公…