什么是子程序?
子程序是被其他程序用来完成特定任务的程序。子程序可以从微程序主体的任何点调用。通常,许多微程序包含相同的代码段。通过使用包含常用微代码段的子程序,可以节省微指令。
例如,为指令生成操作数有效地址所需的微操作序列对于所有内存引用指令都是通用的。此序列可以是一个子程序,可以从许多其他程序中调用以执行有效地址计算。
使用子程序的微程序必须有在子程序调用期间存储返回地址并在子程序返回期间恢复地址的机制。这可以通过将控制地址寄存器的增量输出放入子程序寄存器并跳转到子程序的开头来实现。
然后,子程序寄存器可以成为将返回到主程序的地址传输的源。构建存储子程序地址的寄存器文件的最佳方法是将寄存器组织成后进先出 (LIFO) 堆栈。
将程序控制转移到子程序的指令有不同的名称。最常用的名称是调用子程序、跳转到子程序、分支到子程序或分支并保存地址。
调用子程序指令由操作码和指定子程序开头的地址组成。
该指令的执行包括执行以下两个操作:
- 程序计数器 (PC) 中下一个可用指令的地址(返回地址)存储在临时位置,以便子程序知道返回位置。
- 控制转移到子程序的开头。每个子程序的最后一条指令(通常称为从子程序返回)将返回地址从临时位置转移到程序计数器。这导致程序控制转移到其地址最初存储在临时位置的指令。
子程序调用用以下微操作实现:
SP ← SP − 1 | 它可以递减堆栈指针。 |
M[SP] ← PC | 它用于将 PC 的内容压入堆栈。 |
PC ← 有效地址 | 它可以将控制转移到子程序。 |
如果当前子程序调用另一个子程序,新的返回地址将被压入堆栈,依此类推。从最后一个子程序返回的指令由以下微操作实现:
PC ← M[SP] | 它用于弹出堆栈并将内容转移到 PC。 |
SP ← SP + 1 | 它可以递增堆栈指针。 |
通过使用子程序堆栈,所有返回地址都由硬件在一个单元中自动存储。程序员不必担心或记住返回地址存储在哪里。
递归子程序是调用自身的子程序。如果只有一个寄存器或内存位置可以保存返回地址,并且递归子程序调用自身,它将结束之前的返回地址。
这是不可取的,因为重要信息会被破坏。如果为子程序的每次使用都采用不同的存储位置,而另一个更低级别的使用仍然处于活动状态,则可以解决此问题。
使用堆栈时,每个返回地址都可以压入堆栈而不会破坏任何以前的值。这解决了递归子程序的问题,因为下一个要退出的子程序始终是最后调用的子程序。
广告