计算机系统:基于x86+Linux平台
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3.2 计算机系统核心层之间的关联

高级编程语言编译器将高级语言源程序转换为机器级目标代码,这个过程包含多个步骤,包括词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成和目标代码优化等。可将整个过程划分为前端和后端两个阶段,通常把中间代码生成及之前的步骤称为前端。因此,前端主要完成对源程序的分析,把源程序切分成一些基本块,并生成中间语言表示,后端在分析结果正确无误的基础上,把中间语言表示(中间代码)转化为目标机器支持的机器级语言程序。

每一种程序设计语言都有相应的标准规范,如C语言有C90和C99等标准规范。一方面,编译器开发者必须按照编程语言标准规范设计编译器前端,才能向高级语言程序员提供可正确工作的编译器。另一方面,程序员必须按照语言标准规范编写源程序,源程序才能被编译器正确处理。若程序员不了解语言标准规范,或编写了不符合语言标准规范的高级语言源程序,编译过程就会出错,或者编译出的目标程序运行结果不符合预期。

语言标准规范中有以下三种行为需要程序员注意。

未定义行为(undefined behavior),指符合语言标准规范但未明确指定其结果的行为。若源程序包含未定义行为,则目标程序的每次运行结果可能不同,或在不同平台下运行结果不同。例如,C语言标准规定,最小负整数除以-1的结果未定义,故在不同平台中运行该程序,可能得到不同的结果。

未指定行为(unspecified behavior),指语言标准规范列出多种供编译器选择的行为结果,不同编译器可能选择不同的行为结果。若源程序包含未指定行为,则采用不同的编译器进行编译或采用一款编译器的不同版本进行编译,目标程序的运行结果可能不同。例如,对于程序段“int i=1; f(i++,i++);”,C语言标准规定,函数调用的参数求值顺序未指定,故有的编译器可能按“f(1,2)”处理,有的编译器可能按“f(2,1)”处理。

实现定义行为(implementation-defined behavior),指语言标准规范的实现(如编译器)需要在文档中说明其选择的未指定行为。若源程序包含实现定义行为,在相同环境下运行可得到相同的结果,但将程序移植到另一个环境时,运行结果可能不同。例如,C语言标准规定,char类型是带符号还是无符号整数,是实现定义行为,故程序员不应假设char是带符号或无符号整数。

编译器后端的设计应遵循ISA规范和应用程序二进制接口(Application Binary Interface, ABI)规范。正如1.3.1节提到的,ISA是对指令系统的一种规定或结构规范,ISA定义了一台计算机可以执行的所有指令的集合,以及每条指令执行什么操作、所处理的操作数存放的地址空间和操作数类型等。因为翻译程序的后端将生成能够在目标机器中运行的机器目标代码,所以,它必须按照目标机器的ISA规范生成相应的机器目标代码。不符合ISA规范的目标代码,将无法在根据该ISA规范而设计的计算机上正确运行。

ABI是为运行在特定ISA及特定操作系统上的应用程序规定的一种机器级目标代码层接口,包含了运行在特定ISA及特定操作系统上的应用程序所对应的目标代码生成时必须遵循的约定。ABI描述了应用程序和操作系统之间、应用程序和所调用的库函数之间、不同组成部分(如过程或函数)之间在较低层次上的机器级代码接口。例如,过程之间的调用约定(如参数和返回值如何传递等)、系统调用约定(系统调用的参数和调用号如何传递以及如何从用户态陷入操作系统内核等)、目标文件的二进制格式和函数库使用约定、机器中寄存器的使用规定、程序的虚拟地址空间划分等。不符合ABI规范的目标程序,将无法在根据该ABI规范提供的操作系统运行环境中正确运行。

ABI不同于应用程序接口(Application Program Interface,API)。API定义了较高层次的源程序代码和库之间的接口,通常是与硬件无关的接口。因此,同样的源程序代码可以在支持相同API的任何系统中进行编译以生成目标代码。在ABI相同或兼容的系统上,一个已经编译好的目标代码则可以无须改动而直接运行。

在ISA层之上,操作系统向应用程序提供的运行时环境需要符合ABI规范,同时,操作系统也需要根据ISA规范来使用硬件提供的接口,包括硬件提供的各种控制寄存器和状态寄存器、原子操作、中断机制、分段和分页存储管理部件等。如果操作系统没有按照ISA规范使用硬件接口,则无法提供操作系统的重要功能。

在ISA层之下,设计处理器时需要根据ISA规范来设计相应的硬件接口供操作系统和应用程序使用,不符合ISA规范的处理器设计,将无法支撑操作系统和应用程序的正确运行。

总之,计算机系统能够按照预期正确地工作是不同层次的多个规范相互支撑的结果,计算机系统的各抽象层之间如何进行转换,最终都是由这些规范来定义的。不管是系统软件开发者、应用程序开发者,还是处理器设计者,都必须以规范为准绳,即要以手册为准。计算机系统中的所有行为都是由各种手册确定的,计算机系统也是按照手册构建的。因此,如果要了解程序的确切行为,最好的方法就是查手册。

本书所用平台为IA-32/x86-64+Linux+GCC+C语言,Linux操作系统下一般使用system V ABI,因此,推荐读者上网查阅C语言标准、system V ABI手册和Intel指令系统手册。