实验检测编译过程中的链接作用

本文探讨了编译过程中链接器如何将多个目标文件的逻辑地址统一转换为可执行文件中的连续地址。通过反汇编示例展示了单个源文件生成的目标文件地址总是从0x0开始,而在最终的可执行文件中,这些地址被重新安排以避免冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
名称:实验检测编译过程中的链接作用
说明:以前一直不太了解编译过程中链接是到底干嘛的(其具体的作用是什么),只浅浅的了解到这个阶段就是将各个目标文件连接在一起,至于为什么要连接,怎么连接,不是很清楚。
最近在复习操作系统的时候,了解到,链接阶段的一个功能就是将各个目标文件中的逻辑地址转化为最终可执行文件的的统一的逻辑地址。
这么说吧,每一个源文件生成单独生成的目标文件,其地址(逻辑地址)都是从0x0开始的,而最终生成的可执行文件的逻辑地址也是从0x0开始的,这样的话,那不是有很多个从0x0开始的指令了吗?链接过程就是解决这样的问题的,在这个阶段,所有的目标文件逻辑地址被统一编址,
原来的各个目标文件的指令的地址在可执行文件中被重新安排。
下面的反汇编程序可以看出这一点。

00000000004004ed <test_a>:  //(test_a:在最终可执行文件中开始的地址)
00000000004004fb <test_b>:  //(test_b:在最终可执行文件中开始的地址)
0000000000400516 <main>:    //(main:在最终可执行文件中开始的地址)

同时通过反汇编程序,也能了解到每一种可执行文件确实有差别(window下的和linux等不同操作系统下的)。每个可执行文件的开头还有一些初始化部分等。

*/

//文件test_a中的代码:
void test_a()
{
    int a = 10;
    return ;
}

//文件test_a.o的反汇编

test_a.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <test_a>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
   b:   90                      nop
   c:   5d                      pop    %rbp
   d:   c3                      retq   

代码说明:虽然具体的汇编指令看不懂什么意思,但第一行是第一条指令的逻辑地址。
各列的意思大概是,(地址,指令所对应的机器代码,最后一列是汇编代码)
//文件test_a中的代码:
void test_b()
{
    int b = 5;
    return ;
}


//文件test_b.o的反汇编
test_b.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <test_b>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   c7 45 fc 05 00 00 00    movl   $0x5,-0x4(%rbp)
   b:   90                      nop
   c:   5d                      pop    %rbp
   d:   c3                      retq   

代码说明:可以看到第一条指令也是从地址0x00开始的。
//文件main中的代码:
#include "test.h"

void test_c()
{
    int c = 30;

}

int main()
{
    int m = 20;
    test_a();
    test_b();

    return 0;
}

//文件main.o的反汇编


main.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <test_c>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   c7 45 fc 1e 00 00 00    movl   $0x1e,-0x4(%rbp)
   b:   5d                      pop    %rbp
   c:   c3                      retq   

000000000000000d <main>:
   d:   55                      push   %rbp
   e:   48 89 e5                mov    %rsp,%rbp
  11:   48 83 ec 10             sub    $0x10,%rsp
  15:   c7 45 fc 14 00 00 00    movl   $0x14,-0x4(%rbp)
  1c:   b8 00 00 00 00          mov    $0x0,%eax
  21:   e8 00 00 00 00          callq  26 <main+0x19>
  26:   b8 00 00 00 00          mov    $0x0,%eax
  2b:   e8 00 00 00 00          callq  30 <main+0x23>
  30:   b8 00 00 00 00          mov    $0x0,%eax
  35:   c9                      leaveq 
  36:   c3                      retq   

代码说明:main函数第一条指令也是从0x00开始的(这里的第一条指令不是main函数而是test_c的相关内容)
//最后链接完成的可执行文件的反汇编
main:     file format elf64-x86-64


Disassembly of section .init:

00000000004003a8 <_init>:
  4003a8:   48 83 ec 08             sub    $0x8,%rsp
  4003ac:   48 8b 05 45 0c 20 00    mov    0x200c45(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
  4003b3:   48 85 c0                test   %rax,%rax
  4003b6:   74 05                   je     4003bd <_init+0x15>
  4003b8:   e8 33 00 00 00          callq  4003f0 <__gmon_start__@plt>
  4003bd:   48 83 c4 08             add    $0x8,%rsp
  4003c1:   c3                      retq   

Disassembly of section .plt:

00000000004003d0 <__libc_start_main@plt-0x10>:
  4003d0:   ff 35 32 0c 20 00       pushq  0x200c32(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  4003d6:   ff 25 34 0c 20 00       jmpq   *0x200c34(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  4003dc:   0f 1f 40 00             nopl   0x0(%rax)

00000000004003e0 <__libc_start_main@plt>:
  4003e0:   ff 25 32 0c 20 00       jmpq   *0x200c32(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  4003e6:   68 00 00 00 00          pushq  $0x0
  4003eb:   e9 e0 ff ff ff          jmpq   4003d0 <_init+0x28>

00000000004003f0 <__gmon_start__@plt>:
  4003f0:   ff 25 2a 0c 20 00       jmpq   *0x200c2a(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  4003f6:   68 01 00 00 00          pushq  $0x1
  4003fb:   e9 d0 ff ff ff          jmpq   4003d0 <_init+0x28>

Disassembly of section .text:

0000000000400400 <_start>:
  400400:   31 ed                   xor    %ebp,%ebp
  400402:   49 89 d1                mov    %rdx,%r9
  400405:   5e                      pop    %rsi
  400406:   48 89 e2                mov    %rsp,%rdx
  400409:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  40040d:   50                      push   %rax
  40040e:   54                      push   %rsp
  40040f:   49 c7 c0 b0 05 40 00    mov    $0x4005b0,%r8
  400416:   48 c7 c1 40 05 40 00    mov    $0x400540,%rcx
  40041d:   48 c7 c7 16 05 40 00    mov    $0x400516,%rdi
  400424:   e8 b7 ff ff ff          callq  4003e0 <__libc_start_main@plt>
  400429:   f4                      hlt    
  40042a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

0000000000400430 <deregister_tm_clones>:
  400430:   b8 3f 10 60 00          mov    $0x60103f,%eax
  400435:   55                      push   %rbp
  400436:   48 2d 38 10 60 00       sub    $0x601038,%rax
  40043c:   48 83 f8 0e             cmp    $0xe,%rax
  400440:   48 89 e5                mov    %rsp,%rbp
  400443:   77 02                   ja     400447 <deregister_tm_clones+0x17>
  400445:   5d                      pop    %rbp
  400446:   c3                      retq   
  400447:   b8 00 00 00 00          mov    $0x0,%eax
  40044c:   48 85 c0                test   %rax,%rax
  40044f:   74 f4                   je     400445 <deregister_tm_clones+0x15>
  400451:   5d                      pop    %rbp
  400452:   bf 38 10 60 00          mov    $0x601038,%edi
  400457:   ff e0                   jmpq   *%rax
  400459:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000400460 <register_tm_clones>:
  400460:   b8 38 10 60 00          mov    $0x601038,%eax
  400465:   55                      push   %rbp
  400466:   48 2d 38 10 60 00       sub    $0x601038,%rax
  40046c:   48 c1 f8 03             sar    $0x3,%rax
  400470:   48 89 e5                mov    %rsp,%rbp
  400473:   48 89 c2                mov    %rax,%rdx
  400476:   48 c1 ea 3f             shr    $0x3f,%rdx
  40047a:   48 01 d0                add    %rdx,%rax
  40047d:   48 d1 f8                sar    %rax
  400480:   75 02                   jne    400484 <register_tm_clones+0x24>
  400482:   5d                      pop    %rbp
  400483:   c3                      retq   
  400484:   ba 00 00 00 00          mov    $0x0,%edx
  400489:   48 85 d2                test   %rdx,%rdx
  40048c:   74 f4                   je     400482 <register_tm_clones+0x22>
  40048e:   5d                      pop    %rbp
  40048f:   48 89 c6                mov    %rax,%rsi
  400492:   bf 38 10 60 00          mov    $0x601038,%edi
  400497:   ff e2                   jmpq   *%rdx
  400499:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004004a0 <__do_global_dtors_aux>:
  4004a0:   80 3d 91 0b 20 00 00    cmpb   $0x0,0x200b91(%rip)        # 601038 <__TMC_END__>
  4004a7:   75 11                   jne    4004ba <__do_global_dtors_aux+0x1a>
  4004a9:   55                      push   %rbp
  4004aa:   48 89 e5                mov    %rsp,%rbp
  4004ad:   e8 7e ff ff ff          callq  400430 <deregister_tm_clones>
  4004b2:   5d                      pop    %rbp
  4004b3:   c6 05 7e 0b 20 00 01    movb   $0x1,0x200b7e(%rip)        # 601038 <__TMC_END__>
  4004ba:   f3 c3                   repz retq 
  4004bc:   0f 1f 40 00             nopl   0x0(%rax)

00000000004004c0 <frame_dummy>:
  4004c0:   48 83 3d 58 09 20 00    cmpq   $0x0,0x200958(%rip)        # 600e20 <__JCR_END__>
  4004c7:   00 
  4004c8:   74 1e                   je     4004e8 <frame_dummy+0x28>
  4004ca:   b8 00 00 00 00          mov    $0x0,%eax
  4004cf:   48 85 c0                test   %rax,%rax
  4004d2:   74 14                   je     4004e8 <frame_dummy+0x28>
  4004d4:   55                      push   %rbp
  4004d5:   bf 20 0e 60 00          mov    $0x600e20,%edi
  4004da:   48 89 e5                mov    %rsp,%rbp
  4004dd:   ff d0                   callq  *%rax
  4004df:   5d                      pop    %rbp
  4004e0:   e9 7b ff ff ff          jmpq   400460 <register_tm_clones>
  4004e5:   0f 1f 00                nopl   (%rax)
  4004e8:   e9 73 ff ff ff          jmpq   400460 <register_tm_clones>

00000000004004ed <test_a>:
  4004ed:   55                      push   %rbp
  4004ee:   48 89 e5                mov    %rsp,%rbp
  4004f1:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
  4004f8:   90                      nop
  4004f9:   5d                      pop    %rbp
  4004fa:   c3                      retq   

00000000004004fb <test_b>:
  4004fb:   55                      push   %rbp
  4004fc:   48 89 e5                mov    %rsp,%rbp
  4004ff:   c7 45 fc 05 00 00 00    movl   $0x5,-0x4(%rbp)
  400506:   90                      nop
  400507:   5d                      pop    %rbp
  400508:   c3                      retq   

0000000000400509 <test_c>:
  400509:   55                      push   %rbp
  40050a:   48 89 e5                mov    %rsp,%rbp
  40050d:   c7 45 fc 1e 00 00 00    movl   $0x1e,-0x4(%rbp)
  400514:   5d                      pop    %rbp
  400515:   c3                      retq   

0000000000400516 <main>:
  400516:   55                      push   %rbp
  400517:   48 89 e5                mov    %rsp,%rbp
  40051a:   48 83 ec 10             sub    $0x10,%rsp
  40051e:   c7 45 fc 14 00 00 00    movl   $0x14,-0x4(%rbp)
  400525:   b8 00 00 00 00          mov    $0x0,%eax
  40052a:   e8 be ff ff ff          callq  4004ed <test_a>
  40052f:   b8 00 00 00 00          mov    $0x0,%eax
  400534:   e8 c2 ff ff ff          callq  4004fb <test_b>
  400539:   b8 00 00 00 00          mov    $0x0,%eax
  40053e:   c9                      leaveq 
  40053f:   c3                      retq   

0000000000400540 <__libc_csu_init>:
  400540:   41 57                   push   %r15
  400542:   41 89 ff                mov    %edi,%r15d
  400545:   41 56                   push   %r14
  400547:   49 89 f6                mov    %rsi,%r14
  40054a:   41 55                   push   %r13
  40054c:   49 89 d5                mov    %rdx,%r13
  40054f:   41 54                   push   %r12
  400551:   4c 8d 25 b8 08 20 00    lea    0x2008b8(%rip),%r12        # 600e10 <__frame_dummy_init_array_entry>
  400558:   55                      push   %rbp
  400559:   48 8d 2d b8 08 20 00    lea    0x2008b8(%rip),%rbp        # 600e18 <__init_array_end>
  400560:   53                      push   %rbx
  400561:   4c 29 e5                sub    %r12,%rbp
  400564:   31 db                   xor    %ebx,%ebx
  400566:   48 c1 fd 03             sar    $0x3,%rbp
  40056a:   48 83 ec 08             sub    $0x8,%rsp
  40056e:   e8 35 fe ff ff          callq  4003a8 <_init>
  400573:   48 85 ed                test   %rbp,%rbp
  400576:   74 1e                   je     400596 <__libc_csu_init+0x56>
  400578:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  40057f:   00 
  400580:   4c 89 ea                mov    %r13,%rdx
  400583:   4c 89 f6                mov    %r14,%rsi
  400586:   44 89 ff                mov    %r15d,%edi
  400589:   41 ff 14 dc             callq  *(%r12,%rbx,8)
  40058d:   48 83 c3 01             add    $0x1,%rbx
  400591:   48 39 eb                cmp    %rbp,%rbx
  400594:   75 ea                   jne    400580 <__libc_csu_init+0x40>
  400596:   48 83 c4 08             add    $0x8,%rsp
  40059a:   5b                      pop    %rbx
  40059b:   5d                      pop    %rbp
  40059c:   41 5c                   pop    %r12
  40059e:   41 5d                   pop    %r13
  4005a0:   41 5e                   pop    %r14
  4005a2:   41 5f                   pop    %r15
  4005a4:   c3                      retq   
  4005a5:   66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  4005ac:   00 00 00 00 

00000000004005b0 <__libc_csu_fini>:
  4005b0:   f3 c3                   repz retq 

Disassembly of section .fini:

00000000004005b4 <_fini>:
  4005b4:   48 83 ec 08             sub    $0x8,%rsp
  4005b8:   48 83 c4 08             add    $0x8,%rsp
  4005bc:   c3                      retq   


代码说明:可以看到这里的test_a、test_b、main函数等内容已经不是从0x00开始了,而是按照指令的位置重新排序了。
要说明的是,这个简短的程序的第一条指令并不是就运行main函数中的内容,而是要做一定的初始化工作。如切换上下文中的环境等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值