程序设计语言
现在除了底层人员,一般的开发人员所说的程序语言都是高级语言了,但是对于安全人员,底层开发人员来说远不止这些,主要有下面
- 高级语言
就是现在所通用的类人类语言的编程语言,比如c,c++,python,ruby这种。书写代码通俗易懂 - 汇编语言
对于逆向人员这个真是再熟悉不过了,就不多说了。汇编语言是针对CPU架构来说的 - 机器语言
这个也很好理解,就是字节码,汇编语言其实是对字节码的封装再解释
语言的转换
- 翻译
把某种语言的源从程序,在不改变语意的条件下,转换成另外一种语言程序:目标语言程序 - 编译
专门由计算机的高级语言转为低级语言,就是把整个程序都翻译过来 - 解释
接受某高级语言的一个语句输入,进行解释并控制计算机执行,马上得到这句的执行结果,然后再接受下一句
编译的转换过程
- 两阶段转换
编译 ---> 运行
这种转换的时候,通过编译器直接把源程序转换为机器语言,目标程序可直接执行
- 三阶段转换
编译 ---> 汇编 ---> 运行
当进行这种转换的时候,编译器编译的时候回首先产生汇编文件,然后通过汇编文件的编译器再生成目标文件
- 编译时:
源程序——>编译程序->汇编语言 -
汇编时:
汇编程序-> 目标代码 -
运行时:
初始数据->运行子程序目标代码->计算结果
- 编译时:
编译程序概述
自然语言的翻译
- 先识别句子中的一个个单词
- 分析句子的语法结构
- 根据句子的含义进行初步翻译
- 写出最后的译文
其实编译器的原理跟自然语言的原理一模一样,什么事情只要找一件我们能够理解的事情最对比,就迎刃而解了
编译程序的工作
通过对自然语言的翻译,我们可以总结归纳出把高级语言转换为低级语言的整套历程,下面就对其每个步骤进行一个大概的介绍
词法分析
- 任务
输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词,转换成统一规格,备用。
那么上面的就的话就印出来几个基本概念,下面一一来解释:
- 单词
- 是高级语言中有实在意义的最小语法单位,它由字符构成
- 现在高级语言一般的单词构成
- 基本字(保留字)
- 标示符
用户自己定义的符号 - 常整数
- 运算符
- 界限符
括号,逗号什么的,能表示程序开始或者结束或者其他状态的符号
- 转换
- 对基本字,运算符,界限符的转换
- 对于这类,都是有限的,可以内置好
- 标示符的转换
- 常数的转换
- 转换后的格式:
类号 内码
描述词法规则的有效工具是 正规式和有限自动机
- 对基本字,运算符,界限符的转换
正规式:正则表达式,表示正规集的工具
有限自动机:是一段程序,自动进行语法分析
正规式和有限自动机
语法分析
- 任务
在语法分析的基础上,根据语言的语法规则,把单词符号组成各类的语法单位:短语,子句,语句,过程,程序。
从任务的描述中,又引出了几个概念,首先介绍一下什么叫语法规则:
- 语法规则
就是语言的规则,又称为文法;规定单词如何构成短句,语句,过程和程序。- 语法规则(文法)的表示
\(BNF: A::=B|C\)
上面的公式叫做巴科斯范式。
其中 \(A::\) 在这里表示的意思是定义为,那么整句话的意思就是A定义为B或C。可以跟我们学习英文或者中文的时候做个联想,比如 句子定义为主谓宾 是一个道理。
- 语法规则(文法)的表示
语法举例:等号赋值语句的语法规则
\(A::=V=E\)
首先上面的公式表示为:A
定义为V
赋值为E
.
其中V又被定义为标示符,这里的意思也就是说把E
这个东西赋值给标示符,这种情况就杜绝了赋值号左边是表达式的情况。
那么E
又等是什么呢,E
是表达式,\(E::=T|E+T\),其中T
又可以定位为\(T::=F|T*F\),F
又定义为\(F::=V|(E)|C\).V
上面已经说过了是标示符,C
是常数,那么整个式子就推到下来了
语法分析的方法
语法分析主要有2个指导性的方法:推导(derive) 和归约(reduce)
推导
主要分为 最左推导,最右推导两种。
首先看一下最左推导
- 最左推导
简单点来写就是每次把右边的大写字母,按照规则转换成另外一种东西。 -
举例:
\(A==>V=E\) 等号赋值运算表达式如上,推导出\(x=a+b*50\)
最左推导的逆过程就是最右归约。
因此就有了下面的规律:
- 最左推导,最右规约
- 最右推导,最左规约
语义分析和中间代码生成
语法分析的过程也可以作为用一颗倒着的树来分析,这颗树就叫做语法树。
这是之前推导过的式子,用树状来进行表达了
中间代码
- 任务
对语法分析识别出各类语法范畴,分析其含义,进行和初步翻译,产生于介于源代码和目标代码之间的一种代码。
在进行中间代码生成的时候,主要有2个节点的工作:
- 对每种语法范畴进行静态语义检查
- 若语义正确,就进行中间代码的翻译
同时在中间代码生成的时候,只要有3中生成规则,它们分别是: - 四元式
- 三元式
- 逆波兰式
暂时举个例子先来了解下什么是四元式:
将\(x=a+b*50\)变成中间代码,下图就是最四元式的诠释:
首先,第一步得把50转换为实常数,我们把转换后的结果用T1来表示,现在整个式子变成了\(x=a+b*T1\),紧接着我们来计算\(b*T1\),通过上表的步骤2我们可以看到,*
是运算符,b
是做操作数,T1
是右操作数,T2
是计算后的结果,凡是符合构成算符,左操作数,右操作数,结果这种格式的生成方法,就叫做四元式。
优化
- 任务
对前面产生的中间代码进行加工变换 ,以期在最后阶段能产生更为高效的代码。
- 原则
等价交换
- 考虑优化的方面
- 公共子表达式的提取
- 合并已知量
- 删除无用语句
- 循环优化
目标代码生成
- 任务
把经过优化的中间代码转换成特定机器上的低级语言代码
- 目标代码的形式
- 绝对指令代码
- 汇编指令代码
- 可重定位指令代码
END &补充
至此正编译器的流程已经大概介绍完了,但是我们发现生成流程表上还有表格管理和出错处理这两个模块,那这是干什么呢?下面就补充一下:
表格管理
用来记录源程序的各种信息以及编译过程中的各种状况,会产生表格的主要是编译的前三个阶段,一般来说会产生下面几种表:
- 符号表
- 常数表
- 标号表
- 入口函数表
出错处理
- 任务
如果有源程序有错误,编译程序应设法发现错误,并报告给用户
-
完成
由专门的出错程序来完成
-
错误类型
- 语法错误
在语法分析和词法分析阶段检测出来 - 语义错误
一般在语义分析阶段检查出来
- 语法错误
The post LLVM学习基础之编译原理学习(一):语言 appeared first on cole.
https://ift.tt/2NNefoS LLVM, 编译原理&LLVM, 编译原理学习 October 18, 2018 at 10:46AM
评论
发表评论