C 语言编译链接过程

2018-12-28  本文已影响5人  l蓝色梦幻

C 语言从源代码变成可执行文件经过了以下步骤: 预处理(preprocessing)、编译(compilation)、汇编(assembly)、和连接(linking).

下面, 我们以 hello.c 为例, 看一下整个链接过程.

hello.c

#include <stdio.h>

int main() {
    printf("hello world\n");
    return 0;
}

  1. 预处理 ==> .c -> .i

    预处理包含有以下三种操作

    • 将要包含(include)的文件插入原文件中
    • 将宏定义展开
    • 根据条件编译命令选择要使用的代码操作
    $ gcc -E hello.c -o hello.i
    

    由于最后的预处理后的 .i 文件过大, 这里只展示一部分:

    # 1 "hello.c"
    # 1 "<built-in>" 1
    # 1 "<built-in>" 3
    I# 68 "/usr/include/_stdio.h" 3 4
    # 1 "/usr/include/sys/cdefs.h" 1 3 4
    # 587 "/usr/include/sys/cdefs.h" 3 4
    # 1 "/usr/include/sys/_symbol_aliasing.h" 1 3 4
    # 588 "/usr/include/sys/cdefs.h" 2 3 4
    # 653 "/usr/include/sys/cdefs.h" 3 4
    # 1 "/usr/include/sys/_posix_availability.h" 1 3 4
    
    .......
    
    extern int __vsnprintf_chk (char * restrict, size_t, int, size_t, const char * restrict, va_list);
    # 412 "/usr/include/stdio.h" 2 3 4
    # 2 "hello.c" 2
    int main() {
        printf("hello world\n");
        return 0;
    }
    
  2. 编译 ==> .i -> .s

    编译过程是将上面预处理过后的文件翻译成汇编代码.

    $ gcc -S hello.i -o hello.s
    $ vi hello.s    
    
    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 13
    .globl  _main                   ## -- Begin function main
    .p2align    4, 0x90
        _main:                                  ## @main
    .cfi_startproc
        ## %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    leaq    L_.str(%rip), %rdi
    movl    $0, -4(%rbp)
    movb    $0, %al
    callq   _printf
    xorl    %ecx, %ecx
    movl    %eax, -8(%rbp)          ## 4-byte Spill
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc
                                        ## -- End function
    .section    __TEXT,__cstring,cstring_literals
        L_.str:                                 ## @.str
    .asciz  "hello world\n"
    
    .subsections_via_symbols
    
  3. 汇编 ==> .s -> .o

    将汇编代码翻译成符合一定格式的机器代码.

    gcc -c hello.s -o hello.o
    
  4. 链接 ==> .o -> app

    链接就是将汇编生成的OBJ文件、系统库的OBJ文件、库文件链接起来,最终生成可以在特定平台运行的可执行程序.

    gcc hello.o -o app
    
上一篇下一篇

猜你喜欢

热点阅读