当前位置: 首页 > news >正文

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

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

在这里插入图片描述


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.zskr.cn/news/20154.html

相关文章:

  • 2025年10月通风气楼厂家最新推荐排行榜,屋顶通风气楼,工业厂房通风气楼,节能环保通风气楼公司推荐!
  • 10/13
  • 20234320 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 【服务器知识】HTTP 请求头信息及其用途详细说明 - 详解
  • [GenAI] 大模型微调
  • [GenAI] LoRA微调
  • 2025年10月保洁公司最新权威推荐榜:专业清洁与高效服务的品质之选
  • 2025年10月确有专长培训机构最新推荐榜单:专业课程与高通过率口碑之选
  • 有源探头DC与RMS参数详解:选型与应用指南
  • 2025年10月无锡公考培训机构最新权威推荐榜单:专业师资与高通过率口碑之选
  • 数据敏感型企业为何优选吱吱企业即时通讯?其私有化部署优势详解
  • python实现全端口扫描
  • 3D Gaussian Splatting理论详解 - 教程
  • 2025年10月环氧板定制厂家最新推荐排行榜:专业定制与优质服务的口碑之选!
  • 2025年10月点胶机厂家最新推荐排行榜,自动点胶机,桌面点胶机,三轴点胶机,高精度点胶机公司推荐!
  • ffmpeg源码分析:avformat_open_input()打开媒体流
  • #pragma 和某些编译器指令
  • 基于MATLAB的电力系统潮流计算程序设计与实现
  • springboot图片上传,且同时压缩图片
  • 【题解】QOJ 8351 [IOI 2022 中国国家队集训@南京 Day 2] Ruin the legend
  • 2025年10月抖音推广服务商最新权威推荐榜:专业运营与创意内容助力品牌高效增长!
  • 2025年10月网络营销推广/媒体投放/全案推广/新媒体营销/全媒体推广/推广代运营最新权威推荐榜单
  • 2025年10月安全光栅厂家最新推荐排行榜,超薄/四级/无盲区/红外/光电/小型/冲床/折弯机/机床安全光栅公司推荐
  • 深入解析:扩散模型-图像编辑【An Edit Friendly DDPM Noise Space: Inversion and Manipulations】
  • Docker Desktop 挂载目录实际位置
  • 2025年10月掘进机厂家最新权威推荐榜单:高效施工与卓越性能的首选品牌!
  • 2025年10月南通婚纱照最新权威推荐榜:创意摄影与贴心服务完美结合!
  • 2025 年吸塑纸卡厂家推荐榜:吸塑热压/牙刷/电池/玩具/牙刷烫银纸卡厂家,聚焦环保与品质,帮企业精准选对合作伙伴
  • 2025年10月风机盘管定制厂家最新推荐排行榜:专业定制与优质服务口碑之选
  • 2025年10月液压阀块厂家最新推荐排行榜,专业生产与品质保障的首选!