读《程序是怎样跑起来的》九、十章有感
我在第九章明白了操作系统和应用的关系。监控程序也可以说是操作系统的原型。文字处理软件和表格计算软件等都是应用。
操作系统功能的历史,通过先启动监控系统,程序员就可以根据需要将各种程序加载到内存中运行。随着时代的发展,人们再利用监控程序编写程序的过程中,发现很多程序都有共通的部分。例如,通过键盘输入文字数据、往显示器输入文字数据等。这些处理,在任何程序下都是一样的。而如果每编写一个新的程序都要记述相同的处理的话,那真是太浪费时间了。因此,基本的输入输出部分的程序就被追加到了监控程序中。初期的操作系统就这样诞生了。随着时代的进一步发展,开始有更多的功能被追加到监控程序中,比如,为了方便程序员的硬件控制程序、编程语言处理器以及各种实用程序等,结果就形成了和现在相差不大的操作系统。因此,操作系统本身并不是单独的程序,而是多个程序的集合体。我也明白了,我们制作的应用不是硬件,而是利用操纵系统功能的应用。在操作系统诞生后,就没有必要再编写直接控制硬件的程序了。这样一来,制作应用的程序员就逐渐间隔离开来了。在操作系统这个运行环境下,应用并不是直接控制硬件,而是通过操作系统来间接控制硬件的。变量定义中涉及的内存的申请分配,以及time()和printf()这些函数的运行结果,都不是面向硬件而是面向操作系统的。操作系统收到应用发出的指令后,首先会对指令进行解释,然后会对时钟IC和显示器用的I/O进行控制。
操作系统的硬件控制功能,通常是通过一些小的函数集合体的形式来提供的。这些函数及调用函数的行为统称为系统调用,也就是应用对操作系统的功能进行调用的意思。C语言等高级编程语言并不依存于特定的操作系统。这是因为人们希望不管是Windows还是Linux,都能使用几乎相同的源代码。因此,高级编程语言的机制就是,使用独自的函数名,然后再在编译时将其转换成相应操作系统的系统调用。也就是说,用高级编程语言编写的应用在编译后,就转换成了利用系统调用的本地代码。操作系统和高级编程语言使硬件抽象化。Windows操作系统的主要特征:(1)32位操作系统(2)通过API函数集来提供系统调用(3)提供采用了图形用户界面的用户界面(4)通过WYSIWYG实现打印输出(5)提供多任务功能(6)提供网络功能及数据库功能(7)通过即插即用实现设备驱动的自动设定
我在第十章通过汇编语言了解了程序的实际构成。汇编语言是通过利用助记符来记述程序的。使用汇编器这个工具来进行汇编,通过反汇编,得到人们可以理解的代码。在高级编程语言的源代码中,即使指令和数据在编写时是分散的编译后也会在段定义中集合汇总起来。在汇编语言中,通过跳转指令,可以实现循环和条件分支。汇编语言和本地代码是一一对应的。在个本地代码中,附带上表示其功能的英语单词缩写。例如,在加法运算的本地代码中加上add,在比较运算的本地代码中加上cmp等。这些缩写称为助记符,使用助记符的编程语言成为汇编语言。即使是用汇编语言编写的源代码,最终也必须转换成本地代码才能运行。负责转换工作的程序称为汇编器,转换这一处理本身称为汇编。在将源代码转换成本地代码这个功能方面,汇编契合编译器是同样的。用汇编语言编写的源代码,和本地代码是一一对应的。因而,本地代码也可以反过来转换成汇编语言的源代码。持有该功能的逆变换程序称为反汇编程序,逆变换这一处理本身称为反汇编。如图

通过编译器输出汇编语言的源除了将本地代码进行反汇编这一方法外,通过其他方式也可以获取汇编语言的源代码。大部分C语言编译器,都可以把利用C语言编写的源代码转换成汇编语言的源代码,而不是本地代码。汇编语言的语法是“操作码+操作数”,操作码表示的是指令动作,操作数表示的是指令对象。操作码和操作数罗列在一起的语法,就是一个英文的指令文本。操作码是动词,操作数相当于宾语。能够使用何种形式的操作码,是由CPU的种类来决定的。本地代码加载到内存后才能运行,内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把指令和数据读出,然后再将其存储在CPU内部的寄存器中进行处理。

浙公网安备 33010602011771号