编译并执行是指编译一个程序并把
目标程序装入主内存执行的一种过程。能够执行这种功能的
编译程序称为“装入并执行编译程序”。当编译以同一源语言编写的批量
源程序并逐个执行时,常常用到这种
编译程序。装入并执行
编译程序能够保留在内存中,直到整个批量执行完成为止,而不必在每次编译新的
源程序时都装入内存一次。
它主要的目的是将便于人编写、阅读、维护的高级计算机语言所写作的
源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是
可执行文件。编译器将原始程序(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), 最后打包好的文件就可以给电脑去判读运行了。
早期的计算机软件都是用汇编语言直接编写的,这种状况持续了数年。当人们发现为不同类型的
CPU编写可重用软件的开销要明显高于编写编译器时,人们发明了高级编程语言。由于早期的计算机的
内存很少,当大家实现编译器时,遇到了许多技术难题。
大约在20世纪50年代末期,与机器无关的编程语言被首次提出。随后,人们开发了几种实验性质的编译器。第一个编译器是由美国女性计算机科学家
葛丽丝·霍普(Grace Murray Hopper)于1952年为A-0系统编写的。但是1957年由任职于
IBM的美国计算机科学家
约翰·巴科斯(John Warner Backus)领导的
FORTRAN则是第一个被实现出具备完整功能的编译器。1960年,
COBOL成为一种较早的能在多种架构下被编译的语言。
早期的编译器是用汇编语言编写的。首个能编译自己源程序的编译器是在1962年由
麻省理工学院的Hart和Levin制作的。从20世纪70年代起,实现能编译自己源程序的编译器变得越来越可行,不过还是用
Pascal和
C语言来实现编译器更加流行。制作某种语言的第一个能编译器,要么需要用其它语言来编写,要么就像Hart和Levin制作
Lisp编译器那样,用
解释器来运行编译器。
编译器的构造与优化是
计算机专业的大学课程,课程名称一般为“编译原理”或“编译器”。通常在课程中包含了如何实现一种教学用程序语言的编译器。一个著名的例子是20世纪70年代,瑞士计算机科学家尼克劳斯·维尔特(Niklaus Emil Wirth)用于讲解编译器的构造时使用的PL/0编译器。尽管它很简单,PL/0编译器介绍了这个领域的几个有影响的概念:
有一些编译器输出的代码,将运行于与编译器所在相同类型的计算机和操作系统之上,这种编译器叫做本地编译器。输出可以运行于不同的平台之上的编译器,叫做
交叉编译器。由于
嵌入式系统通常没有软件开发环境,因此,为这类系统开发软件时,通常需要使用交叉编译器。
编译器所输出于
虚拟机上运行之代码,编译器和编译器输出的运行平台有可能相同,也有可能不同。因此,对于这类编译器,不去区分它是本地编译器还是交叉编译器。
即时编译(英语:Just-in-time compilation),又译及时编译、实时编译,
动态编译的一种形式,是一种提高
程序运行效率的方法。通常,程序有两种运行方式:静态
编译与动态
解释。静态编译的程序在执行前全部被翻译为
机器码,而解释执行的则是一句一句边运行边翻译。
即时编译器则混合了这二者,一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。相对于静态编译代码,即时编译的代码可以处理延迟绑定并增强安全性。