【程序是怎样跑起来的】第7章:程序是在何种环境中运行的

运行环境,本地代码,FreeBSD,虚拟机,Java虚拟机,BIOS

Posted by x-jeff on May 15, 2024

博客为参考《程序是怎样跑起来的》一书,自己所做的读书笔记。
本文为原创文章,未经本人允许,禁止转载。转载请注明出处。

1.运行环境=操作系统+硬件

👉第7章热身问答:

  1. 应用的运行环境,指的是什么?
    • 操作系统和计算机本身(硬件)的种类。应用的运行环境通常是用类似于Windows(OS)和AT兼容机(硬件)这样的OS和硬件的种类来表示的。
  2. Macintosh用的操作系统(MacOS),在AT兼容机上能运行吗?
    • 无法运行。不同的硬件种类需要不同的操作系统。
  3. Windows上的应用,在MacOS上能运行吗?
    • 无法运行。应用是为了在特定操作系统上运行而作成的。
  4. FreeBSD提供的Ports,指的是什么?
    • 通过使用源代码来提供应用,并根据运行环境进行整合编译,从而得以在该环境下运行的机制。FreeBSD是一种Unix操作系统。通过在各个环境中编译Ports中公开的代码,就可以执行由此生成的本地代码了。
  5. 在Macintosh上可以利用的Windows环境模拟器称为什么?
    • Virtual PC for Mac。模拟器是指在Macintosh上提供虚拟的Windows环境。
  6. Java虚拟机的功能是什么?
    • 运行Java应用的字节代码。只要分别为各个环境安装专用的Java虚拟机,同样的字节代码就能在各种环境下运行了。

程序的运行环境包含操作系统和硬件两项。例如,2007 Microsoft Office System(下文简称为Office 2007)需要的运行环境,就如表7-1所示。

同一类型的硬件可以选择安装多种操作系统。例如,同样的AT兼容机$^1$中,既可以安装Windows,也可以安装Linux$^2$等操作系统。不过,Windows及Linux操作系统也存在多种版本。根据应用的具体情况,有时只有在特定版本的操作系统上才能运行。

  1. AT兼容机是指,可以和IBM开发的PC/AT在硬件上相互兼容的计算机的总称。称为“PC/AT兼容机”和“DOS/V机”。
  2. Linux是1991年赫尔辛基大学的Linus Torvalds开发的Unix系操作系统。

从程序的运行环境这一角度来考量硬件时,CPU的种类是特别重要的参数。CPU只能解释其自身固有的机器语言。不同的CPU能解释的机器语言的种类也是不同的。例如,CPU有x86、MIPS、SPARC、PowerPC$^1$等几种类型,它们各自的机器语言是完全不同的。

  1. MIPS是美国MIPS科技公司开发的CPU。曾出现过面向MIPS工作站的Windows,不过现在市面上已经不再出售了。SPARC是美国SUN系统开发的CPU。很多工作站都采用了该CPU。PowerPC是美国苹果、IBM、摩托罗拉共同开发的CPU。苹果的Power Mac及IBM的工作站都采用了该CPU。不过现在的Mac采用的是Intel的x86系列CPU。

机器语言的程序称为本地代码(native code)。程序员用C语言等编写的程序,在编写阶段仅仅是文本文件。文本文件(排除文字编码的问题)在任何环境下都能显示和编辑。我们称之为源代码。通过对源代码进行编译,就可以得到本地代码。在市面上出售的用于Windows的应用软件包CD-ROM中,收录的就不是源代码,而是本地代码$^1$(图7-2)。

  1. Windows应用程序的本地代码,通常是EXE文件及DLL文件等形式。

2.Windows克服了CPU以外的硬件差异

计算机的硬件并不仅仅是由CPU构成的,还包括用于存储程序指令和数据的内存,以及通过I/O连接的键盘、显示器、硬盘、打印机等外围设备。而计算机是如何控制这些外围设备的呢?这和计算机的机型有着很大的关系。

Windows操作系统对克服这些硬件构成的差异做出了很大贡献。在介绍Windows之前,让我们先来回顾一下Windows的前身操作系统MS-DOS$^1$广泛使用的时代。在20年前的MS-DOS时代,日本国内市场上有NEC的PC-9801、富士通的FMR、东芝的Dynabook等各种机型的计算机。Windows3.0及3.1问世前后,AT兼容机开始普及,并开始同PC-9801争夺市场份额。

  1. MS-DOS(Microsoft Disk Operating System)是20世纪80年代普遍使用的计算机操作系统。

这些机型虽然都搭载了486及Pentiunm等x86系列的CPU,不过内存和I/O地址的构成等都是不同的,因此每个机型都需要有专门的MS-DOS应用。x86提供有专门用来同外围设备进行输入输出的I/O地址空间(I/O地址分配)。至于各外围设备会分配到什么样的地址,则要由计算机的机型来定。

例如,如果想使用当时大热的文字处理软件——JustSystem的“一太郎”的话,就必须要买各个机型专用的一太郎软件(图7-3(a))。这是因为,应用软件的功能中,存在着直接操作计算机硬件的部分。而这又是为什么呢?原因主要有两点,一是当时MS-DOS的功能尚不完善,二是为了提高程序的运行速度。

不过,随着Windows的广泛使用,这样的局面也得到了大幅改善。因为只要Windows能正常运行,同样的应用(本地代码)在任何机型上都是可以运行的(图7-3(b))。

在Windows的应用软件中,键盘输入、显示器输出等并不是直接向硬件发送指令,而是通过向Windows发送指令来间接实现的。因此,程序员就不用注意内存和I/O地址的不同构成了。因为Windows操作的是硬件而非应用软件,而且针对不同的机型,这些硬件的构成也是有差异的(图7-4)。不过,Windows本身则需要为不同的机型分别提供专用的版本,比如用于AT兼容机的Windows、用于PC-9081的Windows等。

而即便是Windows,也依然无法吸收CPU类型的差异。这是因为,市面上销售的Windows应用软件,都是用特定的CPU的本地代码来完成的。

3.不同操作系统的API不同

接下来让我们看一下操作系统的种类。同样机型的计算机,可安装的操作系统类型也会有多种选择。例如,AT兼容机的情况下,除Windows之外,还可以采用Unix系列的Linux及FreeBSD$^1$等多个操作系统。当然,应用软件则必须根据不同的操作系统类型来专门开发。CPU的类型不同,所对应的机器语言也不同,同样的道理,操作系统的类型不同,应用程序向操作系统传递指令的途径也是不同的。

  1. FreeBSD是1993年加州大学伯克利分校的Computer Systems Research Group在4.4BSD-Lite的基础上开发的Unix系列操作系统。

应用程序向操作系统传递指令的途径称为API(Application Programming Interface)。Windows及Unix系列操作系统的API,提供了任何应用程序都可以利用的函数组合。因为不同操作系统的API是有差异的,因此,将同样的应用程序移植到其他操作系统时,就必须要重写应用中利用到API的部分。像键盘输入、鼠标输入、显示器输出、文件输入输出等同外围设备进行输入输出操作的功能,都是通过API提供的。

在同类型操作系统下,不管硬件如何,API基本上没有差别。因而,针对某特定操作系统的API所编写的程序,在任何硬件上都可以运行。当然,由于CPU种类不同,机器语言也不相同,因此本地代码当然也是不同的。这种情况下,就需要利用能够生成各CPU专用的本地代码的编译器,来对源代码进行重新编译了。

4.FreeBSD Port帮你轻松使用源代码

“既然CPU类型不同会导致同样的本地代码无法重复利用,那么为何不直接把源代码分发给程序呢?”的确,这也是一种方法。部分Unix系列操作系统就对此进行了灵活应用。

Unix系列操作系统FreeBSD中,存在一种名为Ports的机制。该机制能够结合当前运行的硬件环境来编译应用的源代码,进而得到可以运行的本地代码系统。如果目标应用的源代码没有在硬件上的话,Ports就会自动使用FTP$^1$连接到相关站点来下载代码(图7-5)。

  1. FTP(File Transfer Protocol)是连接到互联网上的计算机之间传送文件的协议。

全球很多站点都提供适用于FreeBSD的应用源代码。通过使用Ports可以利用的程序源代码,大约有16000种。这些代码还被按照不同的领域进行了分类整理,可以随时拿来使用。

FreeBSD上应用的源代码,大部分都是用C语言来记述的。FreeBSD等Unix系列操作系统中,都带有标准的C编译器。C编译器可以结合FreeBSD的运行环境生成合适的本地代码。因而,使用FreeBSD的同时,肯定也会享受到Ports带来的益处。可以说Ports能够克服包含CPU在内的所有硬件差异的系统。而且,Ports这个术语,表示的是porting(移植)的意思。而根据不同的运行环境来重新调整程序,一般也称为“移植”。

5.利用虚拟机获得其他操作系统环境

即使不通过移植,也可以使用别的方法来运行其他操作系统的应用。这里我们要介绍的方法就是利用虚拟机软件。比如计算机上安装Macintosh的“Virtual PC for Mac”。通过利用该虚拟机,我们就可以在Macintosh的Mac操作系统上运行Windows应用了。

6.提供相同运行环境的Java虚拟机

除虚拟机的方法之外,还有一种方法能够提供不依赖于特定硬件及操作系统的程序运行环境,那就是Java。

大家说的Java,有两个层面的意思。一个是作为编程语言的Java,另一个是作为程序运行环境的Java。同其他编程语言相同,Java也是将Java语法记述的源代码编译后运行。不过,编译后生成的并不是特定CPU使用的本地代码,而是名为字节代码的程序。字节代码的运行环境就称为Java虚拟机(JavaVM,Java Virtual Machine)。Java虚拟机是一边把Java字节代码逐一转换成本地代码一边运行的。

例如,在使用用于AT兼容机的Java编译器和Java虚拟机的情况下,编译器会将程序员编写的源代码(sample.java)转换成字节代码(sample.class)。而Java虚拟机(java.exe)则会把字节代码变换成x86系列CPU适用的本地代码,然后由x86系列CPU负责实际的处理。

在程序运行时,将编译后的字节代码转换成本地代码,这样的操作方法看上去有些迂回,但由此可以实现同样的字节代码在不同的环境下运行。如果能够结合各种类型的操作系统和硬件作成Java虚拟机,那么,同样字节代码的应用就可以在任何环境下运行了(图7-7)。

  1. PDA(Personal Digital Assistant)是指可以放入手提包中的小型手持计算机。也称为“手持设备”。

Windows有Windows专用的Java虚拟机,Macintosh也有Macintosh专用的Java虚拟机。从操作系统方面来看,Java虚拟机是一个应用,而从Java应用方面来看,Java虚拟机就是运行环境。虽然这样看起来Java虚拟机全是好处,但其实也有不少问题。其中一点就是,不同的Java虚拟机之间无法进行完整互换。这是因为,想让所有字节代码在任意Java虚拟机上都能运行是比较困难的。而且,当我们使用只适用于某些特定硬件的功能时,就会出现在其他Java虚拟机上无法运行,或者功能使用受限等情况。

另一点就是运行速度的问题。Java虚拟机每次运行时都要把字节代码变换成本机代码,这一机制是造成运行速度慢的原因。为此,目前业界也在努力改善这一问题,比如把首次变换后的本地代码保存起来,第2次以后直接利用本地代码,或是对字节代码中处理较为费时的部分进行优化(改善生成的本地代码质量)等。

7.BIOS和引导

程序的运行环境中,存在着名为BIOS(Basic Input/Output System)的系统。BIOS存储在ROM中,是预先内置在计算机主机内部的程序。BIOS除了键盘、磁盘、显卡等基本控制程序外,还有启动“引导程序”的功能。引导程序是存储在启动驱动器起始区域的小程序。操作系统的启动驱动器一般是硬盘,不过有时也可以是CD-ROM或软盘。

开机后,BIOS会确认硬件是否正常运行,没有问题的话就会启动引导程序。引导程序的功能是把在硬盘等记录的OS加载到内存中运行。虽然启动应用是OS的功能,但OS并不能自己启动自己,而是通过引导程序来启动。