第15课 - 编译过程简介
1. 编译器做了什么
(1)预编译:
l 处理所有的注释,以空格代替。
l 将所有的#define删除,并且展开所有的宏定义。
l 处理条件编译指令#if,#ifdef,#elif,#else,#endif。
l 处理#include,展开被包含的文件。
l 保留编译器需要使用的#pragma指令。
预处理指令:gcc -E file.c -o hello.i
(2)编译
l 对预处理的文件进行一系列的词法分析,语法分析和语义分析:
词法分析主要分析关键字,标示符,立即数等是否合法。
语法分析主要分析表达式是否遵循语法规则。
语义分析在语法分析而定基础上进一步分析表达是否合法。
l 分析结束后进行代码优化生成相应的汇编代码文件。
编译指令:gcc -S file.c -o hello.s
(3)汇编
汇编器将汇编代码转变为机器可以执行的指令。每个汇编语句几乎都对应一条机器指令。
汇编指令:gcc -c file.s -o hello.o
// test.h
/*
This is the header file for test.c
*/
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
int g_global = 10;
// test.c
#include "test.h"
#define LOW 0
#define HIGH 255
int max(int a, int b)
{
return MAX(a,b);
}
int main()
{
int c = max(LOW, HIGH); // Call max to get the larger number
return 0;
}
- 连接器的意义
连接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。
- 模块拼装
静态链接
动态链接
小结:
(1) 编译器将编译工作主要分为预处理,编译和汇编三步。
(2) 连接器的工作是把各个独立的模块链接成为可以执行的程序。
(3) 静态链接在编译器完成,动态链接在运行期完成。
原文地址:https://www.cnblogs.com/free-1122/p/9706901.html