When the user presses ENTER(ASCII 10), the code should subtract 10 then branch to GSEND and go to halt but instead it is doing some weird loop. code follows:
.orig x3000
MAIN
LEA R0, STR1 ;R0 points to STR1, which is the memory where we store the string.
JSR GETSTR ;Get a string from the user
PUTS ;Print the string
HALT
;Data – Change these for testing
.blkw 50 ;Change this value when testing between 50 and 150.
;Save space for string storage. Note that this effectively limits your string
;size to 50 which is the number of zs below.
STR1 .stringz "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
GETSTR
;save registers
ST R2, GS_SR2
ST R3, GS_SR3
ST R4, GS_SR4
LD R4, GS_LR4
ADD R2, R0, #0
GSTOP
GETC ;get character
ADD R3, R0, R4 ;if newline skip to end
BRZ GSEND
STR R0, R2, #0 ;store letter in STR1
OUT
ADD R2, R2, #1 ;increment R2
BRNZP GSTOP
GSEND
ADD R0, R2, #0
;reset registers
LD R2, GS_SR2
LD R3, GS_SR3
RET
GS_SR0 .fill 0
GS_SR2 .fill 0
GS_SR3 .fill 0
GS_SR4 .fill 0
GS_LR4 .fill -10
.end
code should reprint the entire string and halt. i can't tell if it just never reaches RET or is getting sent somewhere else.
The JSR
instruction performs a call. A call does two things: transfers control to the designated label, and also, puts the place (here in main
, a code address) to return to in R7
. In order for GETSTR
to successfully return to main
, it must have that same return address that main
put into R7
via the JSR
instruction.
However, it does not, because the trap invoking instruction (here GETC
) repurposes R7
for the return address from the trap. So, in some sense, use of GETC
wipes out one R7
value so that GETC
can use R7
to return back to GETSTR
. So, when GETSTR
tries to use R7
via RET
, it returns not to where should go, but to the return address in R7
, which is within GETSTR
right after the GETC
since that is how R7
was last used — hence the weird loop.
Just need to save & restore R7
the same way as some of the other registers already being done.