深入浅出计算机组成原理
徐文浩
bothub 创始人
70432 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 62 讲
深入浅出计算机组成原理
15
15
1.0x
00:00/00:00
登录|注册

10 | 动态链接:程序内部的“共享单车”

共享运行省内存
加载共享库到内存
复用功能代码
合并代码段
动态链接库的应用
内存利用极致
全局偏移表
程序链接表
相对地址
地址无关码
动态链接
静态链接
课后思考
推荐阅读
总结延伸
PLT和GOT
地址无关
静态链接 vs 动态链接
动态链接

该思维导图由 AI 生成,仅供参考

我们之前讲过,程序的链接,是把对应的不同文件内的代码段,合并到一起,成为最后的可执行文件。这个链接的方式,让我们在写代码的时候做到了“复用”。同样的功能代码只要写一次,然后提供给很多不同的程序进行链接就行了。
这么说来,“链接”其实有点儿像我们日常生活中的标准化、模块化生产。我们有一个可以生产标准螺帽的生产线,就可以生产很多个不同的螺帽。只要需要螺帽,我们都可以通过链接的方式,去复制一个出来,放到需要的地方去,大到汽车,小到信箱。
但是,如果我们有很多个程序都要通过装载器装载到内存里面,那里面链接好的同样的功能代码,也都需要再装载一遍,再占一遍内存空间。这就好比,假设每个人都有骑自行车的需要,那我们给每个人都生产一辆自行车带在身边,固然大家都有自行车用了,但是马路上肯定会特别拥挤。

链接可以分动、静,共享运行省内存

我们上一节解决程序装载到内存的时候,讲了很多方法。说起来,最根本的问题其实就是内存空间不够用。如果我们能够让同样功能的代码,在不同的程序里面,不需要各占一份内存空间,那该有多好啊!就好比,现在马路上的共享单车,我们并不需要给每个人都造一辆自行车,只要马路上有这些单车,谁需要的时候,直接通过手机扫码,都可以解锁骑行。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了动态链接的概念和实现方式。通过动态链接,程序可以在内存中共享代码,节省内存空间。文章详细讨论了动态链接的实现过程,包括动态链接库的创建和调用过程。通过动态链接,不同程序可以共享同一份代码,实现了代码在运行阶段的复用。此外,文章还提到了动态链接在Linux下的应用,以及动态链接的重要性和优势。总的来说,动态链接通过修改“地址数据”来进行间接跳转,实现了代码的灵活调用,为程序开发带来了便利和效率提升。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入浅出计算机组成原理》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(82)

  • 最新
  • 精选
  • fatme
    老师,为什么要采用 PLT 和 GOT 两级跳转,直接用 GOT 有问题吗?

    作者回复: PLT是为了做延迟绑定,如果函数没有实际被调用到,就不需要更新GOT里面的数值。因为很多动态装载的函数库都是不会被实际调用到的。 这个如果要深入细节可以看一下《程序员的自我修养》的7.4小结。

    2019-09-20
    3
    51
  • Java语言多态的实现

    作者回复: 👍不错的例子

    2019-05-17
    5
    41
  • 许山山
    真的写的好棒啊,和操作系统配合食用简直不要太爽

    作者回复: 谢谢支持

    2019-05-17
    2
    21
  • 半斤八两
    所以老师请问下GOT是每个程序都维护一张所以有多张还是每个程序共同维护一张GOT

    作者回复: 每个程序自己维护一张

    2019-05-23
    4
    19
  • 阿锋
    有一个点不明白,虚拟内存中的内容究竟放在哪里,它的内容也应该是放在物理内存里的或者是硬盘里的?是这样吗?

    作者回复: 是的,虚拟内存既然叫做“虚拟”它就是一个抽象概念。要么是已经实际加载到物理内存里了,要么还没有加载或者交换出去在硬盘上。

    2019-05-23
    19
  • 焰火
    浩哥您好,有个问题想请教一下您。 共享库在内存中也是采用分页机制么? 如果是的话,那么怎么解决多进程同时调用共享库的问题呢? 如果不是的话,那么这共享库在内存里就是全加载?

    作者回复: 焰火同学你好 这是个好问题,共享库在内存中也是采用分页机制的。 同时调用共享库只要对应的指令代码是PIC的也就是地址无关的,并不会有什么问题。但是两个进程的数据段是不共享的而已。

    2019-05-21
    2
    15
  • 冯华琴也可叫做冯琴华
    动态代理?上层应用只和代理类交互,具体实现是透明的。

    作者回复: 👍动态代理是个不错的例子

    2019-05-17
    13
  • 活的潇洒
    这一周紧赶慢赶,总算是赶上了更新的进度。day10天学习笔记 https://www.cnblogs.com/luoahong/p/10880416.html

    作者回复: 👍坚持到底就是胜利

    2019-05-17
    2
    7
  • 每个应用程序都会生成自己的GOT表吗?

    作者回复: 不使用动态链接的话就不需要啊

    2019-05-19
    6
  • yang
    在mac上面好像看不出来 PLT 和 GOT 的存在 objdump -source show_me_poor show_me_poor: file format Mach-O 64-bit x86-64 Disassembly of section __TEXT,__text: __text: 100000f70: 55 pushq %rbp 100000f71: 48 89 e5 movq %rsp, %rbp 100000f74: 48 83 ec 10 subq $16, %rsp 100000f78: c7 45 fc 05 00 00 00 movl $5, -4(%rbp) 100000f7f: 8b 7d fc movl -4(%rbp), %edi 100000f82: e8 09 00 00 00 callq 9 <dyld_stub_binder+0x100000f90> 100000f87: 31 c0 xorl %eax, %eax 100000f89: 48 83 c4 10 addq $16, %rsp 100000f8d: 5d popq %rbp 100000f8e: c3 retq _main: 100000f70: 55 pushq %rbp 100000f71: 48 89 e5 movq %rsp, %rbp 100000f74: 48 83 ec 10 subq $16, %rsp 100000f78: c7 45 fc 05 00 00 00 movl $5, -4(%rbp) 100000f7f: 8b 7d fc movl -4(%rbp), %edi 100000f82: e8 09 00 00 00 callq 9 <dyld_stub_binder+0x100000f90> 100000f87: 31 c0 xorl %eax, %eax 100000f89: 48 83 c4 10 addq $16, %rsp 100000f8d: 5d popq %rbp 100000f8e: c3 retq Disassembly of section __TEXT,__stubs: __stubs: 100000f90: ff 25 7a 00 00 00 jmpq *122(%rip) Disassembly of section __TEXT,__stub_helper: __stub_helper: 100000f98: 4c 8d 1d 69 00 00 00 leaq 105(%rip), %r11 100000f9f: 41 53 pushq %r11 100000fa1: ff 25 59 00 00 00 jmpq *89(%rip) 100000fa7: 90 nop 100000fa8: 68 00 00 00 00 pushq $0 100000fad: e9 e6 ff ff ff jmp -26 <__stub_helper> mac 下好像是 100000f82: e8 09 00 00 00 callq 9 <dyld_stub_binder+0x100000f90> dyld_stub_binder 不过,算是知道或者说了解了共享库是通过动态链接 动态生成共享代码的地址,而这个地址一方面是在运行的时候生成,另一方面取决于当前指令的相对地址。这里面有两个重要的表叫PLT(程序链接表)和 GOT(全局位移表)。 额,忽然想起来了一个词语,叫动态绑定,就是运行时才知道是哪个实现。 而静态绑定,就是在编译的时候就已经确定了是哪个实现。 要更好的理解这一讲,需要结合老师推荐的书和linux 环境。

    作者回复: gogo同学, 你好,是的,动态绑定其实和动态链接本质上就是同一个思路。 要看对应的汇编代码,可以找一台云主机装一下Linux,Mac下连readelf这样可以读取elf格式的命令也没有。

    2020-01-03
    3
收起评论
显示
设置
留言
82
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部