所以,我已经完成了一个汇编程序,要求输入一个字符,读取它,回复它,重复四次,然后在连续的字符串中打印出这些字符。然后我想试验子程序(我们还没有在课堂上学到),所以我做了以下子程序来打印一个换行符:
PRINT_NEWLINE ;procedure to print a newline
AND R0,R0,#0 ;clear output register
LD R0,NEWLINE ;load newline into output regiester
TRAP x21 ;print it out
RET ;jump to address in R7
它被“召唤”如下:
JSR PRINT_NEWLINE
运行之后,我注意到一些奇怪的事情,程序似乎在第一次调用PRINT_NEWLINE
后停止了。然后我意识到TRAP在RET
中保存了下一条指令的地址,在本例中是R7
,用于子程序链接的寄存器。这将覆盖R7
中JSR
保存的地址。TRAP
。所以它停止的原因是在RET
例程完成后,它会加载我的TRAP
指令。实际上,由于TRAP
,将pc计数器更改为自身。有点像无限循环。
这一切都很棒,我理解发生了什么,但有没有办法在我的子程序中使用系统JSR
例程,同时仍然使用系统JSR PRINT_NEWLINE
指令?
当然,我可以在PRINT_NEWLINE
调用之后手动将指令的地址存储到另一个寄存器中,然后在我的JMP
子例程的末尾JSR
到该登记册中的地址。
但是,这对我来说似乎是错的,而且我是一名程序员,因此我很懒惰,宁可只是享受其他人的成果,并使用RET
和TRAP
的组合
那么可以在子程序中调用RET
例程并仍然使用{{1}}从该子例程“返回”吗?如何实现这一目标?
谢谢! 的
答案 0 :(得分:3)
在调用R7
之前,您需要在其他地方保存TRAP
的值,然后将其恢复。您还需要对嵌套子例程调用执行此操作。大多数RISC架构需要用户保存某种形式的返回地址;他们没有像x86处理器那样在硬件中实现内存堆栈。