提问人:Sam Perry 提问时间:5/5/2023 更新时间:5/5/2023 访问量:234
Nand2Tetris Mult.Asm 比较失败错误 - Hack 汇编语言
Nand2Tetris Mult.Asm Comparison Failure Error - Hack Assembly Language
问:
尝试为黑客计算机编写乘法程序,无论我以哪种方式旋转它,我都会在硬件模拟器中遇到这种比较失败。
谁能给我指出正确的方向?我做错了什么吗?
谢谢!
@R0
D=M //load first number of equation into the d register from RAM[0]
@R2
M=0 //initialise RAM[2] a.k.a SUM to 0
(LOOP) //begin while loop
@R2
M=D+M //sum = D register value plus M register value
@R1
D=M // D register value is equal to the stored multiplication value i.e second number in the equation
D=D-A //de-increment the value in he d register by 1
@END
D;JLE //while loop break condition - if the value in the D register is less than or equal to zero, break loop
@R0
D=M //load the first number of the equation back into the D register
@LOOP
0;JMP //Loop back to the start of the while loop
(END)
@END // infinite loop
0;JMP
我尝试用不同的逻辑重写代码几次,这种方式对我来说最有意义,但它仍然只能通过 tst 文件中的一些检查
答:
1赞
Erik Eidt
5/5/2023
#1
该代码无法更新 R1,因此它减去 1 以测试结束条件,但将 R1 保留为原始值。
因此,在 D=D-A 之后需要 M=D 来更新 R1。
建议直接使用 -1 而不是 -A,因为后者依赖于 R1 的地址是常量 1,这有点出乎意料。
也许是以下几点:
@R1
D=M-1 // R1-1, in D
M=D // Store R1-1 back into R1
@END
D;JLE // check R1-1 if <= 0, then exit
如果是我,我也会将 R0 加载到更靠近它使用的位置,而不是在循环的末尾在循环的顶部使用。
这将允许循环以条件分支而不是无条件分支结束:
(LOOP) //begin while loop
@R0
D=M //load the first number of the equation back into the D register
@R2
M=D+M //sum = D register value plus M register value
@R1
D=M-1 // R1-1
M=D // R1=R1-1
@LOOP
D;JGT // R1 > 0 --> repeat the loop
仅供参考,您使用的构造是 do-while 循环而不是 while 循环——区别在于 while 循环迭代零次或多次,但 do-while 总是至少迭代一次(我所说的“迭代”是指运行循环的主体:迭代是循环体的运行,这里是乘数求和)。其效果是,如果 R1 对于初学者来说为 0,则 while 循环将正常工作,而 do-while 则无法正常工作。
为了解决这个问题,你可以保留 do-while 形式,因为它比 while 形式更有效,但在循环的开始、之前和外部为 R1=0 添加一个额外的测试,如果 R1=0 为 true,则跳过整个循环。
评论