假设我们写了一个最简单的c程序,文件名为hello.c。
#include<stdio.h> int main(void) { printf("Hello World!\n");//打印字符串 }
然后我们执行:gcc hello.c -o hello
然后我们就可以得到一个可执行程序:hello
整个过程如下图所示。
这个过程看似简单,其实后面是由许多细节值得我们去学习的。
程序的整个编译过程其实包括以下几个步骤:预处理,编译,汇编,链接。
一. 预处理
预处理命令:gcc -E hello.c -o hello.i
预处理需要完成的任务包括以下几个:
(1)删除所有的“#define”,并展开所有的宏定义。
(2)处理所有的条件预编译指令,比如“#if”,“#ifdef”
(3)处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置。
(4)删除所有的注释
(5)添加行号和文件标识
(6)保留所有的#pragma编译指令
二. 编译
编译命令:gcc -S hello.c -o hello.s
编译过程主要完成的任务是:把预处理后的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码文件。这个过程是最核心和复杂的。
三. 汇编
汇编命令:gcc -c hello.s -o hello.o 或者as hello.s -o hello.o
汇编过程主要完成的任务是:将汇编代码转变成机器可执行的指令。
四. 链接
链接命令:ld -static /usr/lib/ctr1.o /usr/lib/crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2......
链接过程完成的主要任务是:进程代码指令的重定位等。