1.2.3 可执行文件的启动和执行
对于一个存放在硬盘上的可执行文件,可以在操作系统提供的用户操作环境中,采用双击对应图标或在命令行中输入可执行文件名等多种方式来启动执行。在Linux系统中,可以通过shell命令行解释器来执行可执行文件。例如,对于上述可执行文件hello,通过shell命令行解释器启动执行的结果如下:
shell命令行解释器会显示提示符linux>,告知用户它准备接收用户的输入,此时,用户可以在提示符后面输入需要执行的命令名,它可以是一个可执行文件在硬盘上的路径名,后可跟若干参数。例如,上述“./hello”就是可执行文件hello的路径名,其中“./”表示当前目录,hello程序没有参数。在命令后用户需按下Enter键表示结束。图1.9显示了在计算机中启动和执行hello程序的整个过程。
如图1.9所示,shell程序会将用户从键盘输入的每个字符逐一读入CPU寄存器中(对应线①),然后将其保存到主存储器中,在主存的缓冲区形成字符串“./hello”(对应线②)。等接收到Enter按键信息时,shell将调出操作系统内核中相应的服务例程,由内核来加载硬盘上的可执行文件hello到存储器(对应线③)。内核“加载”完可执行文件中的代码及其所要处理的数据(这里是字符串“hello,world\n”)后,将hello第一条指令的地址送到程序计数器(PC)中,CPU永远都将PC中的内容作为将要执行的指令的地址,因此,处理器随后开始执行hello程序,它将加载到主存的字符串“hello,world\n”中的每个字符从主存取到CPU的寄存器中(对应线④),然后将CPU寄存器中的字符送到显示器显示(对应线⑤)。
图1.9 启动和执行hello程序的整个过程
从上述过程可看出,用户程序被启动执行,必须依靠操作系统的支持,包括提供人机接口环境(如外壳程序)和内核服务例程。例如,shell命令行解释器就是操作系统外壳程序,它为用户提供了一个启动程序执行的环境,用来对用户从键盘输入的命令进行解释,并调出操作系统内核来加载用户程序(用户从键盘输入的命令所对应的程序)。显然,用来加载用户程序并使其从第一条指令开始执行的操作系统内核服务例程也是必不可少的。
此外,在上述过程中,还涉及键盘、硬盘和显示器等外部设备的操作,这些底层硬件不能由用户程序直接访问,此时,也需要依靠操作系统内核服务例程的支持,例如,用户程序需要调用内核的read系统调用服务例程读取硬盘文件,或调用内核的write系统调用服务例程把字符串“写”到显示器上等。
键盘、硬盘和显示器等外部设备简称为外设,也称为I/O设备,其中,I/O是Input/Output(输入/输出)的缩写。外设通常由机械部分和电子部分组成,并且两部分通常是分开的。机械部分是外部设备本身,而电子部分则是控制外部设备工作的I/O控制器或I/O适配器。外设通过I/O控制器或I/O适配器连到主机,I/O控制器或I/O适配器统称为设备控制器。例如,键盘接口、打印机适配器、显示控制卡(简称显卡)、网络控制卡(简称网卡)等都是设备控制器,属于I/O模块。
从图1.9可以看出,程序的执行过程就是数据在CPU、主存储器和I/O模块之间流动的过程,所有数据的流动都是通过总线、I/O桥接器等进行的。在总线上传输数据之前,需要先将其缓存在存储部件中,因此,除主存本身是存储部件以外,在CPU、I/O桥接器、设备控制器中也有存放数据的缓冲存储部件,例如,CPU中的通用寄存器、设备控制器中的数据缓冲寄存器等。
小贴士
计算机的硬件可以分成主机和外设两部分,主机中的主要功能模块是CPU、主存和各个I/O模块。因为早期计算机的主要功能部件由一条单总线相连,这条总线被称为系统总线,所以,发展为多总线后,就把连接主机中主要功能模块的各类总线统称为 系统总线。因此,多总线计算机中的处理器总线、存储器总线和I/O总线都属于系统总线。不过,Intel架构中将连接CPU和北桥芯片的处理器总线特指为系统总线,也称为 前端总线(Front Side Bus,FSB)。
外部设备种类繁多,且具有不同的工作特性,因而它们在工作方式、数据格式和工作速度方面存在很大差异。此外,CPU、主存等计算机主机部件采用高速元器件实现,使得主机部件和外设之间在技术特性上有很大差异,它们各有自己的时钟和独立的时序控制,两者之间采用完全异步的工作方式。为此,在各个外设和主机之间必须要有相应的逻辑部件来解决它们之间的同步与协调、工作速度的匹配和数据格式的转换等问题,这类逻辑部件统称为 I/O模块(有些书中也称为 I/O接口)。从功能上来说,各种设备的I/O控制器或适配器都是I/O模块。通常,I/O模块中有数据缓冲寄存器、命令字寄存器和状态字寄存器,它们统称为 I/O端口。为了能够访问这些端口,需要对其进行编址,所有I/O端口的地址组成的空间称为 I/O空间。I/O空间可以和主存空间统一编址,也可以单独编址,前者称为 统一编址方式或 存储器映射方式,后者称为 独立编址方式。