目录
在LC-3的编程中,有时候需要重复调用一些子程序,但是又不能像c语言一样定义函数,但是LC-3提供了相当的机制供我们使用
TRAP机制调用子程序
在上一篇文章【LC-3简易四子棋(深大计系1实验4) 思路+代码+详细注释】中,我们提到:
对于输入输出,我们通过一些“伪操作”进行“系统调用”来实现读取字符,输出字符,可是这些操作的本质是TRAP机制来完成的调用
TRAP调用
TRAP将目标中断矢量(也就是trap的操作数,比如TRAP x21
操作数是0x21)的高位补0得到一个数x,然后去内存x处寻找下一条指令的地址,即将内存x处的值压入PC寄存器中
比如TRAP x21
,内存x0021处,存的是子程序首地址,这个地址会被压入PC
TRAP返回
函数都要返回,那么TRAP会在进入子程序之前,将返回地址存到R7
- 在一个子程序的最后,必须使用
RET
指令,即JSRR R7
跳转到R7寄存器对应的地址
这意味着我们不能够在子程序里面不经保存就修改R7的值,这样会使得子程序无法返回,上一篇文章提到的【在一个子程序里不保存R7就调用另一个子程序,最终结果不正确】就是因为这个问题导致的
因为TRAP的操作数只有8位,所以支持256个子程序
例子 TRAP x21 (系统函数)输出字符源码
在LC-3的系统函数中,x21负责输出一个字符,字符的值存放在R0
我们可以看看它的源码,首先找到0x0021内存处,查看真正的起始地址,可以看到是0x0430
我们跳转到0x0430查看源码
可以看到,子程序调用第一步就是保存要用的寄存器的值,然后开始读取KBSR键盘输入标志位,死循环直到键盘输入标志位为1,之后读取数据到R0,然后RET,注意所有子程序都要RET
模拟栈
方法介绍
因为LC-3这种调用机制,使得函数只能被调用一层,多层调用需要不断的保存返回地址,而R7将会被覆盖!
因此,递归就难以实现了,但是我们可以通过模拟一个栈,来实现保存函数的参数,返回地址,返回值,来实现递归函数
我们将要实现一个这样的函数来计算等差数列的前n项和
int func(int x)
{