编译——编译过程(一)

前言

一般我们在写代码的时候,写完直接点击编译运行,但是却并未思考,编译这个过程到底发生了什么;实际上,当前的很多IDE(如Visual Studio)都将这个过程忽略了; 也就是从源文件(.cpp)到可执行文件(.exe)中间的过程我们并未过多了解。

.cpp文件到可执行文件.exe中间的过程如下图所示(预编译(Propressing)–>编译(Compliation)–>汇编(Assembly)–>链接(Linking))4个步骤,执行这四个阶段的程序(预处理器、编译器、汇编器、和链接器)一起构成了编译系统。

1 预编译(Preprocessing)

主要是处理源代码文件中的预编译指令,例如#xxxx,从.cpp文件变成.i文件

  1. 预编译指令的展开 所谓展开就是复制 #include的内容
  2. 添加行号和文件名等调试信息
  3. 删除注释
  4. 处理编译器指令
序号 预处理名称 意义
01#define宏定义
02#undef撤销已定义过的宏名
03#include使编译程序将另一源文件嵌入到带有#include的源文件中
04#if #if 的一般含义是如果#if 后面的常量表达式为true, 则编译它与#endif 之间的代码,否则跳过这些代码。命令#endif 标识一个#if 块的结束。#else命令的功能有点像C 语言中的else, #else 建立另一种选择(在#if 失败的情况下)。#elif 命令意义与 else if相同,它形成一个if else-if 阶梯状语句,可进行多种编译选择
05#else
06#elif
07#endif
08#ifdef用#ifdef 与#ifndef命令分别表示“如果有定义”及“如果无定义”,是条件编译的另一种方法
09#ifndef
10#line改变当前行数和文件名称,它们是在编译程序中预先定义的标识符,命令基本形式为:#line number["filename"]
11#error编译程序时,只要遇到#error就会生成一个编译错误提示消息,并停止编译
12#pragma为实现时定义的命令,它允许向编译程序传送各种指令,编译程序可能有一种选择,它支持对程序执行的跟踪。可用#pragma语句指定一个跟踪选择。

还有下列几种预处理宏(是双下划线)
__LINE__表示正在编译的文件的行号
__FILE__表示正在编译的文件的名字
__DATE__表示编译时刻的日期字符串,例如: “25 Dec 2007”
__TIME__表示编译时刻的时间字符串,例如: “12:30:55”
__STDC__判断该文件是不是定义成标准 C 程序

2 编译(Compliation)

编译主要负责识别源代码,并将其转换成优化后的汇编代码,从.i文件变成.s文件(汇编代码文件)
主要工作是对.i文件进行一系列的词法分析等,目的是让编译器知道这写的代码是啥

  1. 词法分析: 主要是将源代码指令识别分解成一个个符号、关键字、数字等
  2. 语法分析: 主要是分析表达式是否合理,例如不允许指针和指针相乘运算等
  3. 语义分析: 在编译阶段主要是静态语义;工作是声明和类型的匹配、类型的转换,经过语义分析之后,所有的表达式都被标注了相对应的类型
  4. 中间语言生成: 将上述的源代码转换成适合用于转换为汇编代码的中间代码;我的理解是将这些代码变得更加简洁(这其中也必然存在拆分动作)
  5. 目标代码生成和优化: a) 所谓的目标代码,其实是优化后的汇编代码; b) 将中间代码转化成汇编代码; c) 再将汇编代码进行优化; d) 最后成为.s文件

4 汇编(Assembly)

汇编是一个理解起来比较简单的过程:对应不同的机器的指令集,将汇编代码一条一条翻译为机器指令
将.s文件变成.o文件(也即目标文件)
汇编器将上一步骤优化后的汇编代码一条一条的转化为机器指令
机器指令(形如:010101111000110101…)是唯一可以被计算机读懂的指令

5 链接(Linking)

链接主要负责将目标文件(.o文件)和库文件整合起来,就像拼图一样
将.o文件和运行时库(Runtime Library)中的目标文件组装成可执行的.exe文件
这个过程就像是拼图一样,将相互需要的文件进行组装(比如a.o文件中调用了b.o文件中的函数等)
备注:什么是运行时库(Runtime Library)?
库其实是支持程序运行的基本函数的集合
是一组目标文件的包,就是一些常用的代码编译成目标文件后打包存放就是所谓的库

参考

https://blog.csdn.net/qq_41523096/article/details/121092139

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值