栈是计算机控制过程调用和返回的常用技术。
栈是一个有序的元素集合,具备后进先出特点,所以只能通过栈顶访问元素。在计算机中操作栈需要三个地址,它们通常保存在处理器寄存器中。
栈指针:栈顶地址。当发生push或者pop操作时,这个指针会加1或者减1,以表示最新的栈顶指针;
栈底:保存栈底单元的地址。当对空栈发生pop操作时,则发生错误;
栈界限:保存最顶端栈单元的地址。当对满栈发生push操作时,则发生错误;
在大多数机器中,栈底是栈块的高端地址,栈界限是栈块的高端地址。因此,栈是从高端地址向低端地址增长。
过程调用和返回,栈针
当处理器处理一个过程调用时,它将返回地址放在栈中。当过程调用执行返回时,就会使用该栈顶地址。
除了返回地址,过程调用还需要传递参数。有三种方式:
1. 如果直接将参数传递到寄存器中,那么调用程序和被调用程序都需要被写入寄存器;
2. 将参数保存在存储器的call指令之后,但是对于可变参数的处理会很困难;
3. 最好的方法就是使用栈。当处理器执行一次过程调用的时候,不仅会保存返回地址,还会保存传递给被调用过程的参数。被调用过程会从栈中访问这些参数,在返回前,返回参数也可以放在栈中返回地址的下面。为一次过程调用保存的整个参数集合和返回地址,就称为一个栈帧;
例子:
有一个过程调用P,P申明了局部变量x1,x2,。过程P会调用过程Q,过程Q申明了局部变量y1,y2。存储在每一个栈帧的第一项是指向前一帧的指针,如果参数的数量和长度是可变的,就需要使用该指针。第二项是该栈帧的过程的返回地址。随后是栈的顶部为局部变量分配空间,局部变量可用于参数传递。
可重入过程
可重入过程是指程序代码的一个副本在同一时间内被多个用户共享。可重入过程的两个特征:程序代码修改自身;每个用户的局部数据必须单独保存。因此可重入过程必须由两部分组成:
1. 永久不变的部分:组成过程的指令;
2. 临时部分:执行调用程序的指针,以及指向程序使用的局部变量的存储地址的指针;
过程的每个执行实例称之为激活,它将执行永久部分的代码,但是拥有自己的局部变量和参数的副本。被激活的相关联的临时部分称为激活记录,调用一个可重入过程时,该过程的激活记录保存在栈中,成为调用过程栈帧的一部分。