大多数语言中 procedure 是核心抽象。 procedure 提供了系统组件之间的接口。procedure 对于大多数编译器来说是基本工作单元。典型编译器会处理一系列 procedures,以及生成对应的代码。这些分离编译出的代码必须与其他编译的代码 link 和执行。
procedure 在分离编译中也扮演了重要角色,这允许软件开发者建立大型软件系统。如果编译器在编译时需要程序的所有文本代码,大型系统就变成不可能实现。想象一下开发过程中每次编译都要重新编译所有的文本代码!因此 procedure 在系统设计和开发中也扮演了重要角色。本章集中在编译器如何实现 procedures。
本章同事讨论编译期和运行时问题。编译器会计划期望的运行时行为,并生成对应的代码,比如标准调用和返回值机制。为了理解调用如何工作,读者需要关注编译期计划和运行时行为的相互作用。
举个例子,编译器必须计划每个 procedure 的存储。在编译器分析 procedure 代码后,编译器建立了存储映射,包括 procedure 计算的每个值类型和大小。指定值的运行时位置。使用这个映射,编译器生成的代码将会在运行时定位,初始化以及释放值的存储位置。代码实现的这些决策会在调用者和被调之间传递。
简单来说,编译器要决定在调用侧在调用时需要保存和保护的环境,然后生成对应的代码来使能运行时。这样的决策包含保存恢复寄存器,评估绑定参数,建立数据结构来确保对于值的正确访问。
概述
Procedures are the building blocks of program. 它们创建了可被控制的执行环境。调用会创建并初始化 procedure 局部存储。保护调用者的环境,建立被调用的环境,然后创建调用与被调用之间的联系。有返回值的被称为函数。
procedure 提供了三种重要的抽象:
- The Call 提供了 procedure 之间的控制转移。
- Name Space 在大多数语言中,procedure call 创建了一个被调用者的 name space 。开发者可以声明只在局部有效的新的名字。这些局部声明会隐藏之前已经定义的同名 item。
- Externl Interface 在大型软件系统中建立重要接口。 linkage convention 定义了映射名字到值和存储位置的规则,会保存调用者运行时的环境,创建被调用者环境。linkage convention 创建了标准方法使得开发者可以调用其他人开发的代码和系统调用。如果没有 linkage convention 编译器必须理解所有被调用的代码。
因此,procedure 很重要。建立名字的可见性和地址,硬件从对应地址加载或者存储。procedure 允许大型软件的编写分成组件开发,linker 和 loader 将组件结合到一起生成可执行文件。
实现 linkage convention 要求编译器与操作系统的配合。编译器必须使用操作系统提供的接口来处理输入和输出,管理内存,与其他进程通信。