对语言、层次和虚拟机的简单理解
最近在读《计算机组成-结构化方法》这本书,开篇第一节就让我受益匪浅,一本好书果然很重要,它能让晦涩的知识变得通俗易懂,通过简单的语言和举例让问题变的清晰。我把这一段记录下来,加强记忆和理解,也分享给你们。书的地址
在方便人使用和方便计算机实现之间存在着巨大的差距。人可能要做X,而计算机只会做Y,这就有问题了。本书的目的就是解释如何解决这个问题。
这个问题可通过两种途径解决,两者都需要设计一个比内含的机器指令更便于人们使用的新的指令集合。这些新的指令集合也构成了一种语言,我们称为L1,对应地把机器中内含的机器语言指令组成的语言叫L0.这两种途径的不同之处在于,采取了不同的方法让只能执行用L0写的程序的计算机执行用L1写的程序。
一种途径是在执行用L1写的程序之前生成一个等价的L0指令序列来替换它,生成的程序全部由L0执行组成。计算机执行等校的L0程序来替代原来的L1程序,这种技术称为翻译。
另一种途径是用L0写一个程序,将L1的程序作为输入数据,按顺序检查它的每条指令,然后直接执行等效的L0指令序列,计算出结果。它不需要事先生成一个L0语言的新程序。我们把这种方法称为解释,把执行它的程序称为解释器。
翻译和解释其实是类似的。在这两种方法中,L1的指令最终都是通过执行等校的L0指令序列来实现的。区别在于,翻译时整个L1程序都先转换为L0程序,然后L1程序就被抛弃,新的L0程序被装入计算机中执行。在执行过程中,运行的都是新生成的L0程序,控制计算机的也是L0程序。
而解释时,每条L1指令被检查和译码之后将立即执行,不生成翻译后的程序。这里,控制计算机的是解释器,对它来说,L1程序只是数据。这两种方法都得到了广泛的应用,而且日益多用二者的综合。
与其顾名思义地去理解翻译和解释这两个概念,不如想象存在一种以L1为机器语言的假象的计算机(虚拟机)。让我们把这种虚拟机定义为M1(相应地,把原来的以L0为机器语言的实际的计算机定义为M0);如果这种计算机的成本足够低廉,那就根本不需要L0语言,也不需要执行L0程序的机器了。人们可以单纯用L1写程序并让计算机直接执行。即使使用L1语言的虚拟机太贵或电子电路构造太复杂而不能实际使用,大家还是可以写L1语言的程序,这些程序可以用能直接被现有计算机执行的L0语言程序翻译或解释。换句话说,大家完全可以像虚拟机真正存在一样用他们的语言写程序。
为使翻译或解释现实可行,两种语言L0和L1的差别不能“太”大。这条限制往往意味着,虽然L1比L0好一些,但对多数应用来说还是不够理想。这也许不能达到提出L1的最初目的,即减轻程序员不得不用更适合计算机(而不是人类)的语言来描述算法的负担。不过,情况还没到无可挽回的地步。
显然,解决问题的办法是发明一种比L1更面向人的指令集来取代它,这个指令集也形成一种语言,我们可以称为L2(对应的虚拟机称为M2).人们可以像用L2作为机器语言的虚拟机真正存在一样,用L2写程序,然后将这种程序翻译成L1或由L1写成的解释器来执行。
这种发明一系列语言,每种都比前一种更方便人们使用的步骤,可以无限地继续下去,直到最后找到一种合适的语言。美中语言都以前一种为基础,因此我们可以把使用这种技术的计算机看成一系列层,如图所示,一层在另外一层之上。最底部的语言或层最简单,而最上面的语言或层最复杂。
语言与虚拟机之间存在着重要的对应关系。每种机器都有由它能执行的指令组成的机器语言,也就是说,机器定义了语言。类似地,语言也定义了机器,即机器要能执行用这种语言写的所有程序。当然,由某种语言定义的机器真正用电路实现的话,可能会十分复杂和昂贵,但我们依然可以想象它的存在。以C、C++或java语言作为机器语言的机器确实会很复杂,但用今天的技术实现起来也不难。可以我们有充分的理由不去造这么一台机器:与其他技术比起来,它的成本太高。真正实用的设计应该同时具有成本上的优势,仅仅具有理论上的可行性是不够的。
一般意义上讲,有N层的计算机可被看成N台不同的虚拟机,每一台的机器语言都不相同。我们将交替使用术语“层”和“虚拟机”。只有用L0语言写的程序可以被电路直接执行,不用进行内部翻译或解释。用L1、L2、...、LN写的程序必须经底层解析器或翻译成对应于低层的另一种语言。
为n层虚拟机写程序的程序员不必关心下层的翻译器或解释器,程序由计算机的结构来保证正确执行,而不必管它是由解释器一步步地执行后交给下一个解释器还是电路直接执行。对每种情况,结构都一样:程序被执行了。
多数使用n层计算机的程序员只对顶层感兴趣,这一层与底层的机器语言差别最大。然而,那些想了解计算机到底是如何工作的人就必须研究所有的层,而那些对设计新计算机或新的层(新的虚拟机)感兴趣的人也必须熟悉所有层。将计算机分为一系列层的概念和技术以及这些层的组成细节构成了本书的主题。