本节将讲述C语言从源码到二进制程序都经历了那些程序
编写hello world代码:
#include <stdio.h> int main(){ printf("hello world!\n"); return 0; }
以linux gcc编译器为例,可分为四个阶段,执行这四个阶段的程序(预处理器、编译器、汇编器和链接器)一起构成了编译系统。
- 预处理阶段:修改原始.c代码,将原始的代码中的头文件的内容插入到.c代码中,一般产生一个.i的文件。例如:执行gcc -E main.c -o main.i得到预编译的文件main.i
-
编译阶段:编译器会将main.i翻译成汇编程序main.s。例如:执行gcc -S main.i -o main.s 得到汇编代码main.s
.file "main.c" .text .section .rodata .LC0: .string "hello world!" .text .globl main .type main, @function main: .LFB0: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 leaq .LC0(%rip), %rdi call puts@PLT movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" .section .note.GNU-stack,"",@progbits .section .note.gnu.property,"a" .align 8 .long 1f - 0f .long 4f - 1f .long 5 0: .string "GNU" 1: .align 8 .long 0xc0000002 .long 3f - 2f 2: .long 0x3 3: .align 8 4:
- 汇编阶段:汇编器是将汇编代码main.s 翻译成机器指令,把这些机器指令打包成目标文件main.o。例如:gcc -c main.s -o main.o
- 链接阶段:链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件(executable file)。