2.链接器的由来

  • 最初的链接概念早在高级编程语言出现之前就已存在

  • 最早程序员用机器语言编写程序,并记录在纸带或卡片上,穿孔表示0,未穿孔表示1(但一修改一条语句,所有的语句就得重新编写)

  • 用符号表示跳转位置,无需修改jmp指令的跳转目标

  • 汇编语言出现

    • 用助记符表示操作码

    • 用符号表示位置

    • 用助记符表示寄存器

    • 最终进行汇编,链接

  • 高级程序设计语言

    • 程序越来越复杂,需多人开发不同的程序模块

    • 子函数(程序)起始地址和变量起始地址是符号定义(definition)

    • 调用子程序(函数或过程)和使用变量即是符号的引用(reference)

    • 一个模块定义的符号可以被另一个模块引用

    • 最终须编译链接,链接时须在符号引用处填入定义处的地址

  • 链接操作的步骤

    1. 确定符号引用关系(符号解析)——>符号和定义的关系

    2. 合并相关.o文件

    3. 确定每个符号的地址

    4. 在指令中填入新地址

    也就是说,链接过程分为两部分:1. 符号解析(1),2. 重定位(2,3,4)

  • 使用链接的好处

    1. 模块化

      • 一个程序可以分成很多源程序文件

      • 可构建共享函数库,如数学,libc.a(多人开发,代码重用,开发效率高)

    2. 效率高

      • 时间上,可分开编译:只需重新编译被修改的源程序文件,然后重新链接

      • 空间上,无需包含共享库所有代码:源文件中无需包含共享库函数的源码,只要直接调用即可(例如,只要直接调用printf()函数,无需包含其源码)可执行文件和运行时的内存中只需包含所调用函数的代码而不需要包含整个共享库

  • 链接的本质:合并相同的 "section" 。

在还没有链接之前,可重定位目标文件中对应的地址位置都是从0开始排起,

 [gyhlf@localhost ycsapp]$ objdump -d virtualTest.o
 //此处的程序只是简单的输出"hello,cpp";
 virtualTest.o:     file format elf64-x86-64
 ​
 //可以很容易看出代码的地址位置为虚拟地址空间,如下面main函数的地址为0,接下来0,1,4,9……位置
 Disassembly of section .text:
 ​
 0000000000000000 <main>:
    0:   55                      push   %rbp
    1:   48 89 e5                mov    %rsp,%rbp
    4:   bf 00 00 00 00          mov    $0x0,%edi
    9:   e8 00 00 00 00          callq  e <main+0xe>
    e:   b8 00 00 00 00          mov    $0x0,%eax
   13:   5d                      pop    %rbp
   14:   c3                      retq   

而在链接之后,经过符号解析和重定位之后,映射到了虚拟地址空间后,地址就发生了变化,而这刚好也是链接实现的过程,反汇编后得到的代码地址如下

 
000000000040052d <main>:
   40052d:   55                      push   %rbp
   40052e:   48 89 e5                mov    %rsp,%rbp
   400531:   bf e0 05 40 00          mov    $0x4005e0,%edi
   400536:   e8 d5 fe ff ff          callq  400410 <puts@plt>
   40053b:   b8 00 00 00 00          mov    $0x0,%eax
   400540:   5d                      pop    %rbp
   400541:   c3                      retq   
   400542:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
   400549:   00 00 00 
   40054c:   0f 1f 40 00             nopl   0x0(%rax)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值