gcc编译流程分为4个步骤,分别为:
#include <stdio.h> int main() { printf("hello world!\n"); return 0; }(1)预处理阶段
gcc -E helloworld.c -o helloworld.i选项“-o”是指目标文件,“-i”文件为已经过预处理的C原始程序。以下列出了helloworld.i文件的部分内容:
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwchar (void); wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwchar (wint_t); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getw (FILE*); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putw (int, FILE*); # 2 "helloworld.c" 2 int main() { printf("hello world!\n"); return 0; }由此可见,gcc确实进行了预处理,它把“stdio.h”的内容插入到helloworld.c文件中了。
gcc -S helloworld.i -o helloworld.s以下列出了helloworld.s的内容,可见gcc已经将其转化为汇编了。感兴趣的读者可以分析一下这一行简单的C语言小程序是如何用汇编代码实现的。
.file "helloworld.c" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii "hello world!\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: LFB6: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 andl $-16, %esp subl $16, %esp call ___main movl $LC0, (%esp) call _puts movl $0, %eax leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE6: .def _puts; .scl 2; .type 32; .endef(3)汇编阶段
gcc -c helloworld.s -o helloworld.o(3)链接阶段
gcc helloworld.o -o helloworld运行该可执行文件,出现正确结果
./helloworld