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

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

00000000004004ed :  //(test_a:在最终可执行文件中开始的地址)
00000000004004fb :  //(test_b:在最终可执行文件中开始的地址)
0000000000400516 
: //(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 :
   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 :
   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 :
   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 
: 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 0x19> 26: b8 00 00 00 00 mov $0x0,%eax 2b: e8 00 00 00 00 callq 30 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 :
  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 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 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 :
  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 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 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 
  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 :
  4004c0:   48 83 3d 58 09 20 00    cmpq   $0x0,0x200958(%rip)        # 600e20 <__JCR_END__>
  4004c7:   00 
  4004c8:   74 1e                   je     4004e8 0x28>
  4004ca:   b8 00 00 00 00          mov    $0x0,%eax
  4004cf:   48 85 c0                test   %rax,%rax
  4004d2:   74 14                   je     4004e8 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 
  4004e5:   0f 1f 00                nopl   (%rax)
  4004e8:   e9 73 ff ff ff          jmpq   400460 

00000000004004ed :
  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 :
  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 :
  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 
: 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 40052f: b8 00 00 00 00 mov $0x0,%eax 400534: e8 c2 ff ff ff callq 4004fb 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函数中的内容,而是要做一定的初始化工作。如切换上下文中的环境等。

你可能感兴趣的:(操作系统)