浅谈编译原理

一、引例

#include <stdio.h>
void main(void){
    printf("hello\n");
}

在这里插入图片描述
一个.c源程序需要经过预处理器生成.i文件,再经过编译器生成.s文件,再经过汇编器生成可重定位目标文件.o文件,再与其他.o文件经过链接器生成最终的可执行目标程序。

  1. 预处理阶段。
    主要是处理源文件中以“#”开头的预编译指令。
    1.删除#define并展开宏
    2.处理所有条件预编译指令,如#if, #ifdef, #endif
    3.插入头文件到“#include”处
    4.删除所有注释
    5.添加行号和文件名标识,以便编译时编译器产生调试用的行号信息
    6.保留所有#pragma编译指令。
  2. 编译阶段。
    将预处理得到的预处理文件进行语法分析,词法分析,语义分析,优化后,生成汇编代码文件(汇编语言源程序)。
  3. 汇编阶段。
    利用汇编程序(汇编器)将汇编语言源程序转换成机器指令序列(机器语言程序)。
  4. 链接阶段。
    将多个可重定位的目标文件.o合并以生成可执行文件,其可以被加载到内存中,由系统执行。

二、什么是编译?

首先明确一个概念:

计算机程序设计语言三个层次

计算机程序设计语言分为三个层次:高级语言、汇编语言、机器语言。

  1. 机器语言。
      机器语言是可以被计算机直接理解的0和1构成的序列
      例如指令C706 0000 0002,其中:C706是16进制的操作码,表示移入操作;00000002是两个操作数,这里表示讲操作数0002移到地址0000
      机器语言有以下特点,机器语言有二进制组成,与人类的10进制表示习惯相差很大,且难以记忆,难以阅读,还很容易写错。
    在这里插入图片描述
  2. 汇编语言
      由于机器语言难读,难记的特点,很快就出现了汇编语言。汇编语言引入了助记符,方便读记。
      汇编语言也有缺点:1依赖于特点的机器。2编写效率依然很低,一个简单的数学表达式也需要好几条指令。
    在这里插入图片描述
  3. 高级语言
      为了解决汇编语言编写效率低的问题,就出现了高级语言。这种语言接近人类的表达习惯,不依赖于特定的机器。编写效率比较高,不管多么长的表达式都可以用一条语句就可以简介的表达。
    在这里插入图片描述

程序的翻译

  将一种语言编写的程序转换成完全等效的另一种语言编写的程序称为翻译

编译

  编译的本质就是一种翻译的过程:
    编译:将高级语言翻译成汇编语言或机器语言的过程
在这里插入图片描述

三、编译器

编译器定义:

编译器:把高级语言翻译成汇编语言或机器语言的一个程序。

编译器在系统中的位置。

在这里插入图片描述

  1. 预处理器
    源程序聚合、替换宏,得到预处理的源程序。
    在这里插入图片描述
  2. 可重定位代码
    预处理的源程序经过编译器、会变却处理后得到可重定位的机器代码
    在这里插入图片描述
  3. 加载器
    修改重定位的地址,把修改后的指令和数据放到内存中适当的位置。
    在这里插入图片描述
  4. 链接器
    一些大型的程序经常被分割成多个部分进行编译。因此可重定位的代码要与其他可重定位的目标程序和库文件进行链接。生成可执行的目标机器代码。
    在这里插入图片描述

编译器用什么语言编写的

转知乎

理论上来讲,用什么语言都可以,C\C++\JAVA\ruby等等,如果你现在有了一个不满意的C编译器,可以打开另外一个编译器重写一个自己满意的出来。另外关于最早的C语言编译器,查了一下资料:C语言的原型ALGOL 60语言。(也称为A语言) 1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言。 1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言。 1970年,美国贝尔实验室的Ken Thompson将BCPL进行了修改,并为它起了一个有趣的名字“B语言”。意思是将CPL语言煮干,提炼出它的精华。并且他用B语言写了第一个UNIX操作系统。 而在1973年,B语言也给人“煮”了一下,美国贝尔实验室的D.M.RITCHIE在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。所以,最早的C语言编译器使用B语言写的。

作者:知乎用户
链接:https://www.zhihu.com/question/20369232/answer/14920514
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

C语言编译器就是用来编译C语言的,如果C语言编译器也是C开发的,那么是先有C还是先有C编译器?没有C哪来的C编译器?没有C编译器又怎么去编译C?先有鸡还是先有蛋的问题”C语言编译器是用C语言开发“这句话的正确理解应该是这样的一个过程:

  1. 首先使用汇编语言编写出一个C语言编译器 ①.exe(也就是早起的C编译器);
  2. 有了 ①.exe 之后,就可以用 ①.exe来编译C代码,得到一个程序 ②.exe;
  3. ②.exe的功能就可以是读取文本(即C语言源代码),根据文本的生成相应的汇编代码。
  4. 这里的②.exe 其实就是”用C语言开发的C语言编译器“

四、编译系统的结构

在这里插入图片描述
编译器是如何把高级语言程序编译成汇编语言程序的呢?

借鉴人工英汉翻译

在这里插入图片描述
在这里插入图片描述

  1. 词法分析
    通过词法分析,得到各个单词的词性。
    在这里插入图片描述
  2. 语法分析
    识别句子中的各类短语,得到句子的结构。
    在这里插入图片描述
  3. 语义分析
    根据语义结构分析出,各个短语在句子中的充当什么成分。从而确定各个成分
    在这里插入图片描述
  4. 给出中间表示形式
    在这里插入图片描述

编译器的结构

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值