具有单个 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
我想和 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