【C语言进阶剖析】19、编译过程简介

1 隐藏的事实

编译器是由几部分组成的,包括预处理器,编译器,汇编器,链接器。
在这里插入图片描述
我们写的代码经过预处理器,变成 .i 文件,再经过编译器处理,变成 .s 文件,再经汇编器,生成 .o 文件,最后经链接器,变成可执行文件。
在这里插入图片描述
预处理器,编译器,汇编器,链接器都做了什么呢,我们接着看

2 预编译

  • 处理所有的注释,以空格代替
  • 将所有的 #define 删除,并且展开所有的宏定义
  • 处理条件编译指令 #if,#ifdef,#elif,#else,#endif
  • 处理 #include,展开被包含的文件
  • 保留编译器需要使用的 #pragma

预处理指令实例:gcc -E file.c -o file.i

/*
    19-1.h
    This is a header file.  
*/
char* p = "hello";
int i = 0;

// 19-1.c
#include"19-1.h"
// begin to define macro
#define GREET "hello world!"
#define INC(x) x++
// end
int main(){
    p = GREET;
    INC(i);
    return 0;
}

gcc -E 19-1.c -o 19-1.i
得文件 19-1.i 文件,下面是 19-1.i 文件

# 1 "19-1.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "19-1.c"

# 1 "19-1.h" 1




char* p = "hello";
int i = 0;
# 3 "19-1.c" 2




int main(){
    p = "hello world!";
    i++;
    return 0;
}

可以看到,注释被直接去除,头文件被直接展开,宏定义被直接展开。以 # 开头的信息是给后续编译器其他模块使用的。

3 编译

  • 对预处理文件进行词法分析,语法分析和语义分析
    • 词法分析:分析关键字,标示符,立即数等是否合法
    • 语法分析:分析表达式是否遵循语法规则
    • 语义分析:在语法分析的基础上进一步分析表达式是否合法
  • 分析结束后进行代码优化生成相应的汇编代码文件

编译指令实例:gcc -S file.i -o file.s

gcc -S 19-1.i -o 19-1.s
生成 19-1.s 如下,里面的汇编代码这里不做解析了。
在这里插入图片描述

4 汇编

  • 汇编器将汇编代码转变为机器的可以执行执行
  • 每条汇编语句几乎都有对应一条机器指令

汇编指令示例:gcc -c file.s -o file.o

gcc -c 19-1.s -o 19-1.o
生成文件19-1.o,这里还不是可执行文件。
经过链接器处理才能生成可执行文件:gcc 19-1.o -o 19-1

5 小结

编译过程分为预处理,编译,汇编和链接四个阶段
1、预处理:处理注释,宏以及以 # 开头的符号
2、编译:进行词法分析,语法分析和语义分析等
3、汇编:将汇编代码翻译成机器指令的目标文件

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页