操作系统环境

程序中包含着运行环境这一内容,可以说 运行环境 = 操作系统 + 硬件,操作系统又可以被称为软件,它是由一系列的指令组成的。

先看下一个游戏的运行配置:

操作系统版本:说的就是应用程序运行在何种系统环境,现在市面上主要有三种操作系统环境,windows、Linux、Unix,一般我们玩的大型游戏几乎都是在windows上运行,可以说windows是游戏的天堂。windows操作系统也会有区分,分为32位操作系统和64位操作系统,互不兼容。

处理器:处理器指的就是CPU,你的电脑的计算能力,通俗来讲就是每秒钟能处理的指令数,如果你的电脑觉得卡带不起来的话,很可能就是CPU的计算能力不足导致的。

显卡:显卡承担图形的输入任务,因此又被称为图形处理器(Graphic Processing Unit,GPU),显卡也非常重要。

内存:内存即主存,就是你的应用程序在运行时能够动态分析指令的这部分存储空间,他的大小也能决定你电脑的运行速度。

存储空间:存储空间指的就是应用程序安装所占用的磁盘空间。

CPU只能解释其自身固有的语言。不同的CPU能解释的机器语言的种类也是不同的。机器语言的程序称为 本地代码(native code),程序员用C等高级语言编写的程序,仅仅是文本文件。文本文件(排除文字编码的问题)在任何环境下都能显示和编辑。我们称之为源代码。通过对源代码进行编译,就可以得到本地代码。

1,windows操作系统克服了CPU以外的硬件差异 

计算机的硬件并不仅仅是由CPU组成的,还包括用于存储程序指令的数据和内存,移机通过I/O连接的键盘、显示器、硬盘、打印机等外围设备。

在windows软件中,键盘输入、显示器输出等并不是直接向硬件发送指令。而是通过向windows发送指令实现的。因此程序员就不用注意内存和I/O地址的不同构成了。windows操作的是硬件而不是软件,软件通过windows系统可以达到控制硬件的目的。

2,不同操作系统的API差异性 

同样机型的计算机,可安装的操作系统类型也会有多种选择。例如:AT兼容机除了可以安装windows之外,还可以采用Unix系列的Linux以及FreeBSD(也是一种Unix操作系统)等多个操作系统。当然,应用软件则必须根据不同的操作系统类型来专门开发。CPU的类型不同,所对应机器的语言也不同,同样的道理,操作系统的类型不同,应用程序向操作系统传递指令的体精也不同。

应用程序向系统传递指令的途径称为API(Application Programming Interface)。windows以及Linux操作系统的API,提供了任何应用程序都可以利用的函数组合。因为不同操作系统的API是有差异的,所以,如何要将同样的应用程序移植到另外的操作系统,就必须要覆盖应用所用到的API部分。

键盘输入、鼠标输入、显示器输出、文件输入和输出等同外围设备进行交互的功能,都是通过API提供的。

在同类型的操作系统下,不论硬件如何,API几乎相同。但是,由于不同类型CPU的机器语言不同,因此本地代码也不尽相同。

3,FreeBSD Port帮你轻松使用源代码

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

 全球有很多站点都提供适用于FreeBSD的应用源代码。通过使用Ports可以利用的程序源代码,大约有16000种。根据不同的领域进行分类,可以随时使用。

FreeBSD上应用的源代码,大部分是用C语言来标注的,C编译器可以结合FreeBSD的运行换将来生成合适的本地代码。

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

4,可以使用虚拟机获取其他环境

即使不通过应用程序的移植,在同一个操作系统上仍然可以使用其他的操作系统,那就是虚拟界软件。虚拟机(Virtual Machine)指通过软件的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能实现。

1,提供相同运行环境的java虚拟机

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

java有两层含义,一种是作为编程语言的java;一种是作为程序运行环境的java。

java与其他语言相同,都是通过源代码编译后运行的。不过,编译后生成的不是特定CPU使用的本地代码,而是名为字节代码的程序。直接代码的运行环境就称为java 虚拟机(Java Virtual Machine)。Java虚拟机是一边把java字节代码逐一转换为本地代码一边在运行着。

程序运行时,将编译后的字节代码转换为本地代码,这样的操作看上去有些迂回,但由此可以实现相同的字节码可以在不同的操作系统环境下运行。

windows有专门的windows虚拟机,Macintosh有专门的Macintosh虚拟机。从操作系统来看,java虚拟机就是一个应用,从运行环境上来看,java虚拟机就是运行环境。

 5,BIOS和引导

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

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

利用计算机运行程序大部分都是为了提高效率。例如,Microsoft Word这样的文字处理软件,是用来提高文本文件处理效率的程序,Microsoft Excel 等表格计算软件,是用来提高正本处理效率的程序。这种为了提高特定处理效率的程序统称为应用。

程序员的工作就是编写各种各样的应用来提高工作效率,程序员一般不编写操作系统,但是程序员编写的应用离不开操作系统。

6,操作系统功能的历史

操作系统其实也是一种软件,任何新事物的出现肯定都有它的历史背景,那么操作系统也不是凭空出现的,肯定有它的历史背景。

在计算机尚不存在操作系统的年代,完全没有任何程序,人们通过各种按钮来控制计算机,这一过程非常麻烦。于是,有人开发除了仅具有加载和运行功能的监控程序,这就是操作系统的原型。通过事先启动监控程序,程序员可以根据需要将各种程序加载到内存中运行。虽然仍旧比较麻烦,但是比起在没有任何程序的状态下进行开发,工作量得到了很大的缓解。

 随着时代的发展,人们在利用监控程序编写程序的过程中,发现很多程序都有公共的部分。例如,通过键盘进行文字输入,显示器进行数据展示等,如果每编写一个新的应用程序都需要相同的处理的话,那真是太浪费时间了。因此,基本的输入输出部分的程序就被追加到了监控程序中。初期的操作系统就是这样诞生了。

类似的想法可以共用,人们又发现有更多的应用程序可以追加到监控程序中,比如硬件控制程序,编程语言处理器(汇编、编译、解析)以及各种应用程序等,结果就形成了和现在差异不大的操作系统,也就是说,其实操作系统说是多个程序的集合体。

 

 汇编语言是一种低级语言,也被称为符号语言。汇编语言是第二代计算机语言,在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。用一些容易理解和记忆的字母,单词来代替一个特定的指令,比如:用ADD代表数字逻辑上的加减,MOV代表数据传递等等,通过这种方法,人们很容易去阅读已经完成的程序或者理解程序正在执行的功能,对现有程序的bug修复移机运营维护都变得更加简单方便。

可以说共用思想真是人类前进的一大步,对于解放生产力而言简直是太重要了。

7,要把操作系统放在第一位

对于程序员来说,程序创造的不是硬件,而是各种应用程序,但是如果程序员只做应用不懂硬件层面的知识的话,是无法称为硬核程序员的。

在操作系统诞生之后,程序员不需要在硬件层面考虑问题,所以程序员的数量就增加了。哪怕自称对硬件一窍不通的人也可能制作出一个有模有样的程序。不过,要想称为一个全面的程序员,有一点需要清楚的就是,掌握硬件的基础知识,并借助操作系统进行抽象化,可以大大提高编程效率。

在windows操作系统下,用C语言制作一个具有表示当前时间功能的应用。time()是用来取得当前日期和时间的函数,printf()是把结果打印到显示器上的函数,如下:

在这段代码中,我们主要关注硬件做了哪些事情:

1,通过time_t tm,为time_t类型的变量申请分配内存空间;

2,通过time(&tm) ,将当前的日期和时间数据保存到变量的内存空间中;

3,通过printf(“%s\n”,ctime(&tm)),把变量内存空间的内容输出到显示器上。

应用的可执行文件指的是,计算机的CPU可以直接解释并运行的本地代码,不过这些代码是无法直接控制硬件的,事实上,这些代码是通过操作系统来间接控制硬件的。变量中涉及到的内存分配情况,以及time()和printf()这些函数的运行结果,都不是面向硬件而是面向操作系统到的。操作系统收到应用发出的指令后,首先会对该指令进行解释,然后会对时钟IC和显示器用的I/O进行控制。

计算机中都安装有保存日期和时间的实时时钟(Real-time clock),上面提到的时钟IC就是指该实时时钟。

8,系统调用和编程语言的移植性

操作系统控制硬件的功能,都是通过一些小的函数集合体的形式来提供的。这些函数以及调用函数的行为称为系统调用,也就是通过应用进而调用操作系统的意思。在前面的程序中用到了time()以及printf()函数,这些函数内部也封装了系统调用。

C语言等高级编程语言并不依存于特定的操作系统,这是因为人们希望不管是windows操作系统还是Linux操作系统都能够使用相同的源代码。因此,高级编程语言的机制就是,使用独自的函数名,然后在编译的时候将其转换为系统调用的方式(也有可能是多个系统调用的组合)。也就是说,高级语言编写的应用在编译后,就转换成了利用系统调用的本地代码。

不过,在高级语言中也存在直接调用系统调用的编程语言,不过,利用这种方式做成应用,移植性并不友好。

移植性:移植性指的是同样的程序在不同操作系统下运行时所花费的时间,时间越少证明移植性越好。

9,操作系统和高级编程语言使硬件抽象化 

通过使用操作系统提供的系统调用,程序员不必直接编写控制硬件的程序,而且,通过使用高级编程语言,有时也无需考虑系统调用的存在,系统调用往往是自动触发的,操作系统和高级编程语言能够使硬件抽象化,这很了不起。

下面是一个硬件抽象化的具体实例:

上述C编写的程序,fputs()是用来往文件中写入字符串的函数,fclose()是用来关闭文件的函数。

磁盘就如同树的年轮,磁盘的读写是以扇区为单位的,通过磁道来寻址,如果直接对硬件读写的话,那么就会变为通过磁盘用的I/O指定扇区位置来对数据进行读写了。

但是,在上面代码中,扇区压根就没有出现过传递给fopen()函数的参数,是文件名MyFile.txt和指定文件写入的w。传递给fputs()的参数,是往文件中写入的字符串“你好” 和fp,传递给fclose()的参数,也仅仅是fp,也就是说磁盘通过打开这个文件这个操作,把磁盘抽象化了,打开文件这个操作就可以说是操作硬件的指令。

 下面让我们来看一下代码清单中fp的功能,变量fp中被赋予的是fopen()函数的返回值,该值被称为文件指针。应用打开文件后,操作系统就会自动申请分配用来管理文件读写的内存空间。内存地址可以通过fopen()函数的返回值获得。用fopen()打开文件后,接下来就是通过制定的文件指针进行操作,正因为如此,fputs()和fclose()以及fclose()参数中都制定了文件指针。

由此我们可以得出一个结论,应用程序是通过系统调用,磁盘抽象来实现对硬盘的控制的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值