(十六)编译过程(1):从源文件到汇编文件

本专栏总结王利涛《C语言嵌入式Linux高级编程》第三期课程

一、编译输入输出

  • (1) 输入:C程序源文件;
  • (2)输出:汇编文件,目标文件;
  • (3)编译过程主要做了什么?
    • 从高级语言到低级语言的转变
      • 程序语句:函数 ---->代码段;
      • 变量、常数----->数据段、BSS段、rodata段;
      • 各种辅助信息----->符号表、重定位表。

二、编译过程

  • 基本过程:
    词法分析;
    语法分析;
    词义分析;
    中间代码生成;
    汇编代码生成;
    目标代码生成。

三、编译第一阶段

1)语法分析

  • 从左到右,一个字符一个字符读入源程序;
  • 对源程序的字符流进行扫描,分解成一系列记号:token;
  • 常见记号:
    关键字、标识符(函数名、变量名、标号等)
    字面量(数字、字符串等)
    分界符(分号、逗号等)
  • 将标识符存到符号表,将数字、字符串存放到字符串表。
  • 词法扫描器
    ①该阶段主要由词法扫描器完成,比如lex词法扫描器;
    ②采用有限状态机去解析并识别这些token、分界符、结束符;
    ③词法错误:遇到中文字符、圆角/半角字符会出错。
  • 举例:
    语句:sum = a+b/c;
    包含8个记号:“sun”、“=”、“a”、“+”、“b”、“/”、“c”、“;”

四、编译第二阶段

1)语法分析

  • 前一阶段产生的token序列进行语法分析,看是否构成一个语法上正确的程序,分解成语法短语(程序、语句、表达式等);
  • 语法短语用语法树表示,是一种树形结构,不再是线性序列;

2)语法分析器

  • 专门的语法分析工具:yacc,对输入序列进行分析,构建出语法树;
  • 对于不同的编程语言,编译器开发者只需改变语法规则,而无需为每个编译器写一个语法分析器;
  • 语法错误:syntax error
    在这里插入图片描述

五、编译第三阶段

1)语义分析

  • 检查语法分析输出的语句、程序、表达式有没有错误;
  • 仅仅完成了语法层分析,对程序、语句的真正意义并不了解;
  • 静态语义:在编译期间能确定的语义
    函数实参形参类型匹配及转换;
    不允许使用一个未声明的变量。
  • 动态语义:在运行期间才能确定的语义
    比如:除数为0,

2)语义分析器

  • 经过语义分析后,整个语法树的表达式都被标示了类型;
  • 如果源代码语义上没有问题,就会接下来进入下一个阶段;

3)常见的语言错误(警告)

  • 使用一个未声明的变量或函数;
  • 函数的形参实参、返回类型不匹配、不兼容(默认类型转换后);
  • continue 语句不能出现循环语句之外;
  • break 不能出现在循环或switch语句之外。

六、编译器第四阶段

1)生成中间代码

  • 将语法树转换成中间代码;

2)现代编译器构造

  • 前端:词法分析、语法分析、语义分析;
  • 优化端:对中间代码进行优化;
  • 后端:指令选择,寄存器分配。

3)中间代码

  • 将源代码变成一种内部表示形式,这种形式称为中间代码;
  • 中间代码是一种记号系统,常见的有:三地址码。
  • 语法树是二维树结构,而中间代码可以看作一堆线性序列;
  • 特点:
    非常间接目标代码,类似于伪代码;
    容易生成,容易将其翻译成目标代码。

4)为什么要使用中间代码?

在这里插入图片描述

5)三地址码

  • $arn-linux-gnuebigcc -fdump-tree-gimple main.c
int main()
{
	int sum = 0;
	int a = 2;
	int b = 1;
	int c = 1;
	sum = a+b/c;
	return 0;
}

三地址码↓↓

main()
{
	int D.4226;  //定义了一些临时变量,最终被翻译成寄存器
	int D.4227;
	{
		int sum;
		int a;
		int c;
		sum = 0;
		a = 2;
		b = 1;
		c = 1;
		D.4226 = b/c;
		sum = D.4226+a;
		D.4227 = 0;
		return D.4427;
	}
}

七、编译第五阶段

1)生成汇编

  • 指令选择: 将中间代码翻译成汇编文件;

2)过程

  • 中间代码——》控制流、数据流分析、寄存器分配——》汇编语言;
  • 汇编语言——》汇编器——》目标文件。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值