Nand2Tetris Mult.Asm 比较失败错误 - Hack 汇编语言

Nand2Tetris Mult.Asm Comparison Failure Error - Hack Assembly Language

提问人:Sam Perry 提问时间:5/5/2023 更新时间:5/5/2023 访问量:234

问:

尝试为黑客计算机编写乘法程序,无论我以哪种方式旋转它,我都会在硬件模拟器中遇到这种比较失败。

谁能给我指出正确的方向?我做错了什么吗?

谢谢!

@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 文件中的一些检查

程序集 nand2tetris

评论


答:

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,则跳过整个循环。