C语言编译过程

C语言编译总共分为 预处理、编译、汇编、链接四个阶段。

C语言编译过程

需要注意的是,不同语言的编译过程不同,有些语言不需要编译。

编译过程

下面通过一个简单的C语言例子 hello.c 来演示整个过程

#include <stdio.h>
int main()
{
    printf("Hello world\n");
    return 0;
}

预处理

使用命令将.c的源程序变成了.i的文本文件:

gcc -E hello.c -o hello.i

查看预处理结果 hello.i

cat hello.i

输出结果:

……前面内容太多了省略掉

extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;


extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 864 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 879 "/usr/include/stdio.h" 3 4

# 2 "hello.c" 2

# 2 "hello.c"
int main()
{
    printf("Hello world\n");
    return 0;
}

这一步将原来 #include <stdio.h>中的内容连接到一个文本中

编译

将.i的文本文件生成.cod的文本文件,这就是汇编代码。有的编译器生成以.s或.asm为扩展名的文件

使用命令:

gcc -S hello.i -o hello.s

查看编译结果 hello.s

cat hello.s

输出结果:

    .file    "hello.c"
    .text
    .section    .rodata
.LC0:
    .string    "Hello world"
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    call    puts
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (Uos 8.3.0.3-3+rebuild) 8.3.0"
    .section    .note.GNU-stack,"",@progbits

这一步将文本编译成了程序的汇编代码

汇编

将汇编程序翻译为二进制的目标代码,大多数编译器生成的目标代码为.obj的二进制文件(有些编译程序不生成汇编代码,直接生成目标二进制代码,直接给链接程序,还有些编译程序直接生成可执行代码)

使用命令:

gcc -c hello.s -o hello.o

生成了二进制代码文件hello.o

链接

目标文件本身不能直接运行,链接程序把目标文件转换成最终可以运行的程序,如生成的.exe可执行文件。

使用命令:

gcc hello.o -o hello

生成了可执行文件 hello

使用命令./hello运行 hello程序输出:

hello world
最后修改:2022 年 03 月 02 日
如果觉得我的文章对你有用,请随意赞赏