首页 > 解决方案 > LMC 程序不输出正确的和

问题描述

loop    inp
        sta numa
        sub validate
endthis brp loop
        bra label1
label1  lda numa
        sub validate1
        brp label2
        brz label2
endthis bra loop
label2  lda num
loop    sta num
        add total
        sta total
        sta num
        sub one
        brp loop
        lda total
        out
validate dat 11
validate1 dat 5
numa    dat
num     dat
total   dat 
one     dat 1

该程序将让用户输入 5 到 10 之间的数字,并计算从 1 到用户指定输入的数字之和,并将结果打印在输出显示中。例如,如果用户输入 5,则总和将为 15。

标签: little-man-computer

解决方案


代码存在以下问题:

  • 有些标签不是唯一的,例如loop. 所以这意味着不清楚执行应该在哪里跳转brp loop指令。根据您使用的模拟器,您可以获得不同的行为。您应该为标签使用唯一的名称。

  • 代码的第二部分——计算完成的地方——开始于:

    label2  lda num
    loop    sta num
    

    ...但这只是读取和写入 in 中的内容num,这是无用的。您真的想将输入复制num,因此应该是:

    label2  lda num2
    loop    sta num
    
  • 再往下一点你有这个代码:

    sta total
    sta num
    sub one
    

    ...但这num会用总数覆盖,然后从总数中减去一个。但是,您想从输入数字的倒数值中减去 1,而不是从总数中减去。因此,您真正需要的是获得该倒计时值,然后减去:

    sta total
    lda num    # corrected
    sub one
    
  • 您的程序没有hlt指令,这意味着执行将进入程序的“数据部分”。所以在hlt这里添加:

    lda total
    out
    hlt    # stop execution
    

还有以下几点需要改进:

  • endthis标签从未被引用:它不是必需的。

  • 在这段代码中:

    brp label2
    brz label2
    

    ...该brz指令永远不会导致跳转到label2,因为 0 已经被 捕获brp。它可能会令人困惑,但brp意味着:“非负时分支”,因此当累加器为零时它也会分支。因此,您可以删除它brz label2;不需要。

  • 以下bra指令:

            bra label1
    label1  lda numa
    

    ... 将跳转到label1,否则也将继续执行该行。所以这是一个无用的跳跃。你可以把那条bra label1线拿出来,把标签也去掉。

  • LMC 可以重置为从顶部再次运行。在这种情况下,您必须考虑到数据不会被重置,因此最好在程序开始时使用将数据初始化为初始值的代码。在这种特殊情况下,您需要将总数重置为 0,否则您将添加到上一次运行的总数中。

  • 我建议使用更有意义的名称。例如,label1numa没有真正澄清它们的用途。

建议的解决方案:

          lda zero   # added: initialise total
          sta total
getinput  inp
          sta input
          sub toogreat
          brp getinput
          lda input
          sub minimum
          brp inputok
          bra getinput
inputok   lda input     # corrected
loop      sta countdown
          add total
          sta total
          lda countdown # corrected
          sub one
          brp loop
          lda total
          out
          hlt   # added
toogreat  dat 11
minimum   dat 5
input     dat 4
countdown dat
total     dat 0 
zero      dat 0
one       dat 1

<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.816/lmc.js"></script>


推荐阅读