Question

So, I have finished an assembly program that asks for a character, reads it, echos it, repeats that four times, then prints out those characters in a consecutive string. I then wanted to experiment with subroutines (which we haven't learned about in class yet), so I made the following subroutine to print a newline character to the console:

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

It gets "called" like this:

JSR PRINT_NEWLINE

After running this, I noticed something weird, the program seemed to stop after the first call to PRINT_NEWLINE. Then I realized that TRAP saves the address of the next instruction, which in this case is RET, in R7, the register used for subroutine linking. This overwrites the address which was saved in R7 by JSR. So the reason it appears to stop is that after the TRAP routine finishes, it loads my RET instruction. Which is actually, because of the TRAP, changing the pc counter to itself. Sort of like an infinite loop.

That's all great, and I understand what's going on, but is there a way I can use system TRAP routines inside of my subroutine, while still using the system JSR instruction?

I could, of course, manually store the address of the instruction after the JSR PRINT_NEWLINE call into a different register, and then at the end of my PRINT_NEWLINE subroutine, JMP to the address in that register.

But, that seems wrong to me and, I'm a programmer, therefore I'm lazy, and would rather just enjoy the fruits of other's labor and use the combination of JSR and RET.

So is it possible to call a TRAP routine in a subroutine and still use RET to "return" from that subroutine? How would one accomplish this?

Thanks!

Was it helpful?

Solution

You will need to save the value of R7 somewhere else before calling TRAP and restore it afterward. You will need to do that for nested subroutine calls as well. Most RISC architectures require some form of return address saving by the user; they do not implement a memory stack in hardware like x86 processors do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top