0

对于Little Man Computer (LMC) 模拟器,我有以下任务:

您的代码必须接受 1 到 15 之间的数字。然后必须在显示新总数之前添加数字 2(到提交的数字)。必须重复此过程,直到最终总数达到 14 或 15。此时,程序必须结束。注意:您的最终代码不得输出任何负数。

所以它应该将输出显示为序列 2、4、6、8、10、12、14 或 3、5、7、9、11、13、15。

我面临的问题是,无论我输入 1 到 15 之间的任何数字,它都只是将数字乘以自身并输出。

到目前为止,这是我的代码:

INP
STA 11
ADD 11
OUT
ADD 11
OUT
ADD 11
OUT
HLT

2

我究竟做错了什么?

[![LMC运行图][2]][3]

4

2 回答 2

1

关于你写的一些评论:

所以它应该将输出显示为序列 2、4、6、8、10、12、14 或 3、5、7、9、11、13、15。

这些指令使得不可能获得以 2 开头的输出,因为最小输入值被称为 1,并且程序应该在第一个输出之前将 2 添加到它。这意味着输出的第一个值将至少为 3。

由于输入可以是更大的值(最多 15 个),因此输出序列可以比您指定的更短。例如,如果输入是 10,则输出应该只是 12、14。

这也意味着如果用户输入 14 或 15,程序根本不会产生任何输出。

我面临的问题是,无论我输入 1 到 15 之间的任何数字,它都只是将数字乘以自身并输出。

代码中的行2没有做任何事情,因为在 LMC 语言中,常量值需要伴随DAT助记符:

DAT 2

如果您这样做了,值 2 将存储在邮箱 10 中。但即便如此,您也永远不会在代码中访问该邮箱,因此在执行期间的任何阶段都不会添加 2。

相反,您将输入存储在邮箱 11(这没关系),然后将邮箱 11 添加到该邮箱,这确实导致该数字的两倍。然后你又重复了 2 次,这样你就输出了这个数字的 3 倍和那个数字的 4 倍。

您应该使用标签而不是对邮箱的数字引用(就像您使用 11 所做的那样)。所以你应该有类似的东西:

two DAT 2
sum DAT

然后按如下方式使用这些标签:

    INP
    STA sum ; instead of 11
    ADD two ; this will add 2

有人可以帮我解决我做错的事情吗?

除了上述几点之外,您的尝试还缺少条件循环。它应该在某处验证累积的总和没有达到限制(14 或 15),如果是这样 - 只有这样 - 它应该继续将另一个 2 添加到总和并输出它。

您可以通过进行减法并检查结果是否为负数来有条件地重复代码BRP。因此,根据减法结果,您可以让执行继续循环中的代码,或者让它退出该循环。如果循环,最终它将再次到达这个点,它将重复减法和检查。在某些时候,减法结果会有不同的符号,并且BRP会有不同的反应。这样你就可以跳出循环。

解决方案

这是一个您可以在此处运行的实现(运行代码片段以组装 LMC 代码,然后单击新显示的“运行”按钮以实际运行组装的代码)。

#input: 1
     INP
     STA sum
loop SUB n14  ; compare sum with 14
     BRP end  ; stop when sum is equal or greater...
     LDA sum
     ADD two
     STA sum
     OUT
     BRA loop ; repeat
end  HLT
two  DAT 2
n14  DAT 14
sum  DAT

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

于 2020-10-30T11:44:37.310 回答
0

所以简单来说,

  1. 输入一个数字
  2. 如果它小于零,则中止(分支到结束)
  3. 如果为零,则中止(分支到结束)
  4. 如果大于 14,则中止(分支到结束)
  5. 添加 2
  6. 打印
  7. 分支到 4

您的代码正在读取一个数字,然后将其添加到自身 3 次,每次都打印(如果操作正确,也应该使用循环)。

因为这是一个作业,所以我将留给你弄清楚如何在实际的 LMC 代码中编写它。定义像 2 这样的常量的操作码是DAT,并且使用这个原始指令集,比较两个数字的方法是将它们相减。然后使用“零或正分支”操作码来决定是否循环返回。

于 2020-10-29T18:27:14.193 回答