You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nand2Tetris汇编阶乘程序结果异常求助:输出值偏高

阶乘程序调试问题求助

正在学习Nand2Tetris的汇编语言章节,已经完成mult.asm任务,现在尝试编写一个计算任意输入数阶乘的程序:用户将n输入至R0,程序计算n!并将结果存入R1(需处理F(0)情况)。目前程序的循环计数器能正常终止,但输出结果始终偏高,例如输入3时得到8而非6,附上当前代码,寻求解决建议。

// ================================= Factorial ==================================
// This program calculates the Factorial F of a given number n 
//  At run time:
//      - The user should enter the value of n into R0. R0.e. RAM[0]
//      - The program then calculate the factorial of n    R0.e. F(n)=n!
//           F(n) = n*(n-1)*(n-2)*......*2*1
//      - The result F(n) should be saved in RAM[1]
//          -- You should also consider the F(0) case.
// ==============================================================================


// put your code here

    //set tracker for current loop
    @R1
    M=0
    @R2
    M=1
    @R3
    M=0
    @R4
    M=0
    @R5
    M=0
    @R6
    M=0

(LOOP)
    @R6
    D=M     //D=R6
    @R1
    M=M+D
    @R2
    D=M     //D = R2
    @R4
    M=D     //R4 = R2
    @R0
    D=D-M   //D = R2 - R0
    @END
    D;JGE   //If (R2-R0) > 0 goto END
    @STEP
    D;JLT   //If (R2-R0) < 0 goto STEP


(STEP)
    //Multiplication begins
    // Gets R4 from R6.
    @R6
    D=M // wrting data of r6 into d register

    // Add R1 to it.
    @R1
    D=D+M

    // And write the result back to R6.
    @R6
    M=D

    // Reduce R4 by 1.
    @R4
    D=M-1
    M=D

    // If R4 is still > 0 then loop.
    @STEP
    D;JGT
    //Multiplication ends

    @R2
    M=M+1   //R2++

    @LOOP
    0;JMP   //Got LOOP
(END)
    @END
    0;JMP   //Infinite loop

问题分析与修改建议

核心问题点

  1. 初始值错误:阶乘的初始乘积应为1(0!和1!的结果都是1),但你把R1初始设为0,后续所有运算都会基于0累加,逻辑完全错误。
  2. 乘法逻辑混乱:STEP段的运算顺序搞反了,实际应该用当前阶乘结果R1乘以R2,而非用R6累加R1。
  3. 循环条件错误:当R2等于R0时(比如输入3,R2=3),你直接跳转到END,漏掉了最后一次乘法运算,这是输入3得到8而非6的关键原因之一。
  4. 冗余寄存器:R3、R5完全未使用,属于冗余定义,可以删除。

具体修改步骤

  1. 修正初始值:
    • 将R1初始设为1,因为阶乘的起始值是1;若R0为0,直接跳转到END返回1。
  2. 调整循环条件:只有当R2 > R0时才结束循环,R2等于R0时仍需执行乘法。
  3. 重构乘法逻辑:利用临时寄存器保存当前R1的值,通过累加R2次实现乘法(对应mult.asm的思路),每次循环后R2自增。

修改后的示例代码

// ================================= Factorial ==================================
// This program calculates the Factorial F of a given number n 
//  At run time:
//      - The user should enter the value of n into R0. R0.e. RAM[0]
//      - The program then calculate the factorial of n    R0.e. F(n)=n!
//           F(n) = n*(n-1)*(n-2)*......*2*1
//      - The result F(n) should be saved in RAM[1]
//          -- You should also consider the F(0) case.
// ==============================================================================

    // 初始化:阶乘初始值为1
    @R1
    M=1
    // 循环计数器从1开始
    @R2
    M=1

    // 处理0!的情况:若R0=0,直接结束
    @R0
    D=M
    @END
    D;JEQ

(LOOP)
    // 判断是否已完成所有乘法:R2 > R0则结束
    @R2
    D=M
    @R0
    D=D-M
    @END
    D;JGT

    // 保存当前阶乘结果到临时寄存器R3
    @R1
    D=M
    @R3
    M=D

    // 重置累加器R4为0,准备累加R2次
    @R4
    M=0

(MULT_STEP)
    // 累加R3到R4
    @R3
    D=M
    @R4
    M=D+M

    // R2减1,判断是否还需要累加
    @R2
    D=M-1
    M=D
    @MULT_STEP
    D;JGT

    // 将累加结果存入R1,作为新的阶乘结果
    @R4
    D=M
    @R1
    M=D

    // 循环计数器自增,进入下一轮
    @R2
    M=M+1
    @LOOP
    0;JMP

(END)
    @END
    0;JMP   // 无限循环终止

测试输入3时,程序会依次计算11=1,12=2,2*3=6,最终R1存入6,符合预期;输入0时直接返回1,满足要求。

内容的提问来源于stack exchange,提问作者Boss Fappy200

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:10:43