首页 > 代码库 > 你真的深入理解计算机系统了吗之篇章一:程序与系统的交互
你真的深入理解计算机系统了吗之篇章一:程序与系统的交互
随着计算机的发展以及高级编程语言的出现,应用程序不仅仅要与硬件打交道,还要借助于一些系统的服务,这些系统不仅仅包括操作系统还有编译系统等,我们分别来介绍应用程序是如何与这些系统打交道的。
首先来看程序与编译系统的交互。如今的程序代码规模越来越大,将所有代码都写在一个文件中已经变得不切实际,因此通常将代码按照功能划分到不同的文件中。当一个高级语言写的程序要想能被处理器执行,那它首先要被编译系统的编译器编译为二进制形式的文件,即可重定位目标文件,其次编译系统的链接器还必须将这些可重定位目标文件链接成一个可执行文件。对于编译器如何编译高级语言这里不再累赘,主要讲解一下链接器是如何工作的。
链接器完成的工作主要包括两部分:1.符号解析,2.重定位。在Linux系统中,目标文件通常为ELF格式(windows为PE格式),它由多个节组成,其中包括.text .data .symtab等,.text节中主要是已编译程序的机器代码,.symtab节中主要存放符号,包括全局变量、函数名等。当将可重定位的目标文件链接起来时,它先解析各个可重定位目标文件中引用的符号,如果遇到的符号在自己的符号表不存在,那它就去别的目标文件中的符号表中去寻找,这样就把代码中的每个符号引用与确定的符号定义联系起来。接下来是重定位,首先链接器将所有目标文件的相同类型的节合并为同一类型的聚合节,并将运行时存储器地址赋给这些聚合节以及定义的每个符号,其次链接器修改代码节和数据节中对每个符号的引用,使之指向符号的运行时地址。这样整个链接就完成了,形成的文件也称为可执行目标文件。
再来看程序与操作系统的交互。如今的计算机已不再局限于以前的单道程序的执行,而是多道程序的并发执行,就像我们可以一边听歌一边玩游戏一样,那对于单处理器的计算机来说这是如何实现的呢?大家肯定想到了是进程,毫无疑问,进程这个概念对于计算机系统来说是非常深刻的影响也是很深远的,各位读者可以仔细琢磨它的深刻性!
进程的经典定义就是执行中程序的实例。它提供了一种假象使得我们以为自己在独占处理器和存储器。首先来看独占处理器的假象,在有n个进程的操作系统中,这n个进程轮流执行一个时间片,然后被抢占。其中每个进程中程序计数器(即PC)的值序列与别的进程中的序列是相互独立的,这样就为我们制造了一种处理器只运行自己程序的假象。再来看独占存储器的假象,在一个有n位地址的机器上,地址空间是1—2^n-1的集合,每个进程都有2^n大小的地址空间。其他进程不能访问,至于它的实现主要是虚拟存储器来实现的。
当我们在程序中动态申请块时,像c语言的malloc函数等,这是操作系统的虚拟存储器来为我们分配块的。虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传递数据。
你真的深入理解计算机系统了吗之篇章一:程序与系统的交互