具有单个 MARIE 子程序的 JnS 提供无限循环

JnS with single MARIE Subroutine giving infinite loop

我想和 Marie 做一个简单的乘法运算来做 (a * b) * (c * d)。我可以通过为每个乘法步骤创建一个新的子例程来做到这一点,但我想尝试使用 JnS 来只使用一个子例程。这是我的代码块

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

问题出在我第一次调用循环时,它经历了第一次迭代,通过了 Skipcond,然后跳出子例程回到调用它之后的指令。

这是我第一次使用 JnS,如有任何帮助将不胜感激!

JnS指令将return地址存储在子程序的第一个字中。

(这种方法在 1960 年代很常见,之前处理器的规范是递归调用堆栈——由专用硬件支持,例如具有堆栈指针。PDP-8 执行子例程调用的方式与 MARIE 完全相同。参数也被内联传递,例如,作为参数的数据值在调用之后立即放置(在 PDP-8 JMS 上)并且子例程会将 return 地址推进到参数之后。)

因此,MARIE 子程序需要以一个数据字开始,注意这个数据字不会被执行,而是会被覆盖。

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

进一步,因为任何子程序的第一个字都是数据(代码地址到return到),如果你想在函数的顶部有一个循环,你需要第二个标签— 在数据字之后的第一个 code 指令处。 Jump subr 无法进行循环,因为在 subr 处执行数据字会很糟糕,因为它不是指令。

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