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!
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