如何解决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。
解决方法
代码存在以下问题:
-
有些标签不是唯一的,例如
loop
。所以这意味着不清楚执行应该用brp loop
指令跳转到哪里。根据您使用的模拟器,您可以获得不同的行为。您应该为标签使用唯一的名称。 -
代码的第二部分——计算完成的地方——开始于:
label2 lda num loop sta num
...但这只是读取和写入
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
,因为零已经被brp
捕获。这可能会令人困惑,但brp
的意思是:“非负时分支”,因此当累加器为零时它也会分支。因此,您可以删除该brz label2
;不需要。 -
以下
bra
指令:bra label1 label1 lda numa
... 将跳转到
label1
或者也只是继续该行。所以这是一个无用的跳跃。你可以去掉那bra label1
行,也去掉标签。 -
LMC 可以重置为从顶部再次运行。在这种情况下,您必须考虑到数据不会重置,因此在程序开始时使用将数据初始化为初始值的代码是一种很好的做法。在这种特殊情况下,您需要将总数重新设置为 0,否则您将添加到之前运行的总数中。
-
我建议使用更有意义的名称。例如,
label1
和numa
并没有真正阐明它们的用途。
建议的解决方案:
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>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。