本文作者 TomorrowWu,原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章。觉得好的话,顺手分享到朋友圈吧,感谢支持。
编译器的概念
编译器是一种电脑程序,它会将用某种编程语言写成的源代码(原始语言),转换成另一种编程语言(目标语言)。
主要目的
将便于人编写,阅读,维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是可执行文件。
编译器将原始程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源代码一般为高阶语言 (High-level language), 如 Pascal、C、C++、C# 、Java 等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)
现在编译器的主要工作流程
源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 汇编程序 (assembler) → 目标代码 (object code) → 链接器 (Linker) → 可执行文件 (executables)
工作原理
编译是从源代码(通常为高阶语言)到能直接被计算机或虚拟机执行的目标代码(通常为低阶语言或机器语言)的翻译过程
反编译器:用来从由高阶语言生成的低阶语言代码重新生成高阶语言代码
也有从一种高阶语言生成另一种高阶语言的编译器,或者生成一种需要进一步处理的中间代码的编译器(又叫级联)
编译器的分类
典型的编译器输出是由包含人口点的名字和地址以及外部调用的机器代码所组成的目标文件
一组目标文件,不必是同一编译器产生,但使用的编译器必须采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的可执行程序
在运行过程中,编译器又可分成只依赖于源语言的编译器前端和只依赖于目标语言的编译器后端两大部分,编译器前后端结构如图所示
前端主要负责解析(parse)输入的源程序,由词法分析器和语法分析器协同工作,前端还负责语义(semantic checking)的检查,例如检测参与运算的变量是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树AST(Abstract Syntax Tree),这样后端可以在此基础上进一步优化处理。编译器后端主要负责分析、优化中间代码以及生成机器代码
"本地"编译器
编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码
例如Mac系统编译Golang程序直接生成Mac系统能直接运行的二进制文件
交叉编译器
编译器也可以生成用来在其他平台上运行的目标代码,交叉编译器在生成新的硬件平台时非常有用
例如在Mac上,通过交叉编译Golang程序,生成Windows系统或Linux系统的可执行程序
Java模式
所有Java源程序都会首先被编译成只在这个虚拟机上才能执行的“目标代码”:字节码(Bytecode)
在实时运行时,可以有两种运行方式:一种是编译所获得的字节码由JVM在实际计算机系统上执行;另一种方式是通过Java实时编译器(Just-In-TimeCompiler)将字节码首先转换成本地机可直接执行的目标代码,而后交给实际的计算机系统运行。这实际上是一个两次编译过程,一次是非实时的,一次是实时的。由于第一次是非实时编译,Java编译器生成的是基于JVM的“目标代码”
GCC模式
通过CrossGCC直接生成目标平台的目标代码,从而能够直接在目标平台上运行
需要根据目标平台的不同,选择针对这个平台的CrossGCC
// Mac下编译Linux和windows 64位可执行程序
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
GCC模式和Java模式的不同
- GCC直接生成目标平台的目标代码,而Java模式首先只是生成字节码,只有在有JIT编译器的参与下才会进一步生成目标平台的目标代码
- Java模式虽然可以通过两个编译过程生成目标代码,但是因为两次编译的优化存在相互冲突,最终的目标代码的执行效率也不是很高
- GCC模式由于直接能够生成目标代码,其执行效率一般很高
本文作者 TomorrowWu,原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章。觉得好的话,顺手分享到朋友圈吧,感谢支持。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。