过程控制

控制过程调用和返回的最常用的技术是使用栈。本附录概述了栈最基本的特征,并给出了它们在过程
控制中的使用方法。
栈的实现
栈是一个有序的元素集合,一次只能访问一个元素,访问点称做栈顶。栈中的元素数目,或者说栈的

长度是可变的。只可以在栈顶添加或删除数据项。基于这个原因,栈也称做下推表或后进先出(LIFO)表。

栈的实现需要有一些用于存储栈中元素的单元集合。图 1.25 给出一种典型的方法,在内存(或虚拟存储器)
中为栈保留一块连续的单元。大多数时候,块中只有一部分填充着栈元素,剩余部分供栈增长时使用。正
确操作需要三个地址,这些地址通常保存在处理器寄存器中。
● 栈指针:包含栈顶地址。如果往栈中添加(PUSH)或删除(POP)一项,这个指针减 1 或加 1,
以包含新的栈顶地址。
● 栈底:包含保留块中最底层单元的地址。当往一个空栈中添加一项时,这是所用到的第一个单元。
对一个空栈进行 POP 操作,则发生错误。
● 栈界限:包含保留块中另一端,即顶端单元的地址。如果对一个满的栈进行 PUSH 操作,则发生
错误。
传统上,以及在现在的大多数机器中,栈底是保留的栈块的高端地址,而栈界限是低端地址。因此,
栈是从高端地址向低端地址增长的





过程调用和返回


管理过程调用和返回的最常用的技术是使用栈。当处理器执行一个调用时,它将返回地址放在栈中;
当执行一个返回时,它使用栈顶的地址。对于图 1.26 中的嵌套过程,图 1.27 显示了栈的使用情况。
在过程调用时,通常还需要传递参数,可以把它们传递到寄存器中。另一种可能的方法是把参数保存
在存储器中的 Call 指令后,在这种情况下,参数后面必须是返回单元。这两种方法都有缺陷,如果使用寄
存器,被调用程序和调用程序都必须被写入,以确保正确使用寄存器;而在存储器中保存参数,则很难交
换可变数目的参数。
更灵活的参数传递方法是栈。当处理器执行一次调用时,不仅在栈中保存返回地址,而且保存传递给
被调用过程的参数。被调用过程从栈中访问这些参数,在返回前,返回参数也可以放在栈中返回地址的下
面。为一次过程调用保存的整个参数集合,包括返回地址,称做栈帧(stack frame)

图 1.28 给出了一个例子,过程 P 中声明了局部变量 x1 和 x2,过程 P 调用过程 Q,Q 中声明了局部变
量 y1 和 y2。存储在每个栈帧中的第一项指向前一帧的指针,如果参数的数量与长度是可变的,就需要用
到该指针。第二项是相应于该栈帧的过程的返回点。最后,在栈帧的顶部为局部变量分配空间。局部变量
可用于参数传递。例如,假设在 P 调用 Q 时,它会传递一个参数值,该参数值可存储在变量 y1 中。因此,
在高级语言中,P 例程中的一个指令看起来会如下所示:
CALL Q(y1)
执行该调用时,会为 Q 创建一个新的栈帧(如图 1.28b 所示)
,这包含一个到 P 的栈帧的指针、到 P
的返回值以及 Q 的两个局部变量,其中一个被初始化为由 P 传递的参数。另一个局部变量 y2 是由 Q 在计
算过程中使用的局部变量。在栈帧中包含这样一个局部变量的目的将在后面讨论。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值