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.