loopssubroutinemarie

JnS with single MARIE Subroutine giving infinite loop


I'm trying to do a simple multiplication with Marie to do (a * b) * (c * d). I'm able to do it by making a new subroutine for every multiplication step, but I want to try and use JnS to just use a single subroutine. Heres my chunk of code

Clear
Store result
Input
Output
Store a
Load a
Skipcond 800
Jump negres
Input
Output
Store b
Load b
Skipcond 800
Jump negres
Input
Output
Store c
Load c
Skipcond 800
Jump negres
Input
Output
Store d
Load d
Skipcond 800
Jump negres
Load a
Store X
Load b
Store Y
JnS loop
Load zoop
Store X
Load zoop
Store Y
Load result
Store Y
Load c
Store X
JnS loop
Load zoop
Store X
Load zoop
Store Y
Load result
Store Y
Load d
Store X
JnS loop
Jump halt


loop,        Load zoop
         Load result
         Add Y
         Store result
         Load X
         Subt one
         Store X
         Skipcond 400
         Jump loop
         Load zoop
         JumpI loop


negres,      Load zoop
         Store result
         Jump halt

halt,   Load result
         Output
         Halt

a, DEC 0
b, DEC 0
c, DEC 0
d, DEC 0
zoop, DEC 0
X, DEC 0
Y, DEC 0
one, DEC 1
result, DEC 0

The issue lies in the first time I call loop, it goes through the first iteration, passes the Skipcond then jumps back out of the subroutine to the instruction after where it was called.

This is my first time using JnS, so any help would be greatly appriciated!


Solution

  • The JnS instruction stores the return address in the first word of the subroutine.

    (This approach was common in the 1960's before the norm for processors was a recursive call stack — supported by dedicated hardware, like having a stack pointer.  The PDP-8 did subroutine calls exactly the same way as MARIE.  Parameters were also passed inline, e.g. data values as parameters were placed immediately after the call (on PDP-8 JMS) and the subroutine would advance the return address past the parameters.)

    Thus, MARIE subroutines need to start with a data word, and, note that this data word is not executed, but rather overwritten.

              ...
              JnS subr         # call subr, maybe from main
              ...
              Halt
    
    
    subr,     Hex 0            # placeholder for return address
              load Result      # first instruction of subr
              ...
              JumpI subr       # set program counter = return address
    

    Further, because the first word of any subroutine is data (the code address to return to), if you want to have a loop at the top of the function, you'll need a second label — at the first code instruction, which is after the data word.  Jump subr won't work to make a loop because it would be bad to execute the data word at subr, since it isn't an instruction.

    subr,     Hex 0            # placeholder for return address
    top,      load Result      # first instruction of subr
              ...
              SkipCond 400
              Jump top         # loop to first instruction of subr
              ...
              JumpI subr       # set program counter = return address