浅谈汇编器、编译器和解释器( 二 )


这种被称为“编译器”的新程序可以把用高级语言写的程序转换成汇编语言,再使用汇编器把汇编语言转换成机器可读的程序 。这种程序组合常常被称为“工具链”,因为一个程序的输出就直接成为另一个程序的输入 。
编译语言相比汇编语言的优势体现在从一台计算机迁移到不同型号或者品牌的另一台计算机上的时候 。在计算机的早期岁月里,包括 IBM、DEC、德州仪器、UNIVAC 以及惠普在内的很多公司都在制造除了大量不同类型的计算机硬件 。这些计算机除了都需要连接电源之外就没有太多共同点了 。它们在内存和 CPU 架构上的差异相当大,当时经常需要人们花费数年来将一台计算机的程序翻译成另一台计算机的程序 。
有了高级语言,我们只需要把编译器工具链迁移到新的平台就行了 。只要有可用的编译器,高级语言写的程序最多只需要经过小幅修改就可以在新的计算机上被重新编译 。高级语言的编译是一个真正的革命性成果 。

浅谈汇编器、编译器和解释器

文章插图
1983 发布的 IBM PC XT 是硬件价格下降的早期例子 。
程序员们的生活得到了很好的改善 。相比之下,通过高级语言表达他们想要解决的问题让事情变得轻松很多 。由于半导体技术的进步以及集成芯片的发明,计算机硬件的价格急剧下降 。计算机的速度越来越快,能力也越来越强,并且还便宜了很多 。从某个时间点往后(也许是 80 年代末期吧),事情发生了反转,程序员变得比他们所使用的硬件更值钱了 。
解释器随着时间的推移,一种新的编程方式兴起了 。一种被称为“解释器”的特殊程序可以直接读取一个程序将其转换成计算机指令以立即执行 。和编译器差不多,解释器读取程序并将它转换成一个中间形态 。但和编译器不同的是,解释器直接执行程序的这个中间形态 。解释型语言在每一次执行的时候都要经历这个过程;而编译程序只需要编译一次,之后计算机每次只需要执行编译好的机器指令就可以了 。
顺便说一句,这个特性就是导致人们感觉解释型程序运行得比较慢的原因 。不过现代计算机的性能出奇地强大,以至于大多数人无法区分编译型程序和解释型程序 。
解释型程序(有时也被成为“脚本”)甚至更容易被移植到不同的硬件平台上 。因为脚本并不包含任何机器特有的指令,同一个版本的程序可以不经过任何修改就直接在很多不同的计算机上运行 。不过当然了,解释器必须得先移植到新的机器上才行 。
一个很流行的解释型语言是 perl。用 perl 完整地表达我们的加法问题会是这样的:
$x = 1 + 2虽然这个程序看起来和 C 语言的版本差不多,运行上也没有太大区别,但却缺少了初始化变量的语句 。其实还有一些其它的区别(超出这篇文章的范围了),但你应该已经注意到,我们写计算机程序的方式已经和数学家用纸笔手写数学表达式非常接近了 。
虚拟机最新潮的编程方式要数虚拟机(经常简称 VM)了 。虚拟机分为两大类:系统虚拟机和进程虚拟机 。这两种虚拟机都提供一种对“真实的”计算硬件的不同级别的抽象,不过它们的作用域不同 。系统虚拟机是一个提供物理硬件的替代品的软件,而进程虚拟机则被设计用来以一种“系统独立”的方式执行程序 。所以在这个例子里,进程虚拟机(往后我所说的虚拟机都是指这个类型)的作用域和解释器的比较类似,因为也是先将程序编译成一个中间形态,然后虚拟机再执行这个中间形态 。
虚拟机和解释器的主要区别在于,虚拟机创造了一个虚拟的 CPU,以及一套虚拟的指令集 。有了这层抽象,我们就可以编写前端工具来把不同语言的程序编译成虚拟机可以接受的程序了 。也许最流行也最知名的虚拟机就是 JAVA 虚拟机(JVM)了 。JVM 最初在 1990 年代只支持 Java 语言,但是如今却可以运行 许多 流行的编程语言,包括 Scala、Jython、JRuby、Clojure,以及 Kotlin 等等 。还有其它一些不太常见的例子,在这里就不说了 。我也是最近才知道,我最喜欢的语言 Python 并不是一个解释型语言,而是一个 运行在虚拟机上的语言 !
虚拟机仍然在延续这样一个历史趋势:让程序员在使用特定领域的编程语言解决问题的时候,所需要的对特定计算平台的了解变得越来越少了 。
就是这样了希望你喜欢这篇简单介绍软件背后运行原理的短文 。有什么其它话题是你想让我接下来讨论的吗?在评论里告诉我吧 。


推荐阅读