1

我正在尝试编写一个 LMC 程序,它接受两个整数输入,将它们相除,然后产生商和余数。首先,我将问题分解为 4 个阶段:

1.将 num1 除以 num2 得到商 q。

2.将q和num2相乘得到确切的乘数,并将其存储在num2中。

3.从num1中减去num2,并将答案存储在rem中。

4.输出q和rem。

这是我写的代码:

    INP 
    STA NUM1
    LDA NUM1
    STA ORG
    INP
    STA NUM2
    BRZ END
    LDA 99
    STA Q
    LOOP   LDA NUM1
    BRZ END
    LDA NUM1
    SUB NUM2
    STA NUM1
    LDA Q
    ADD ONE
    STA Q
    BRA LOOP
    LDA Q
    STA NUM3
    LDA NUM2
    SUB ONE
    STA NUM2
    LOOP    LDA NUM2
    BRZ END
    LDA NUM3
    ADD Q
    STA NUM3
    LDA NUM2
    SUB ONE
    STA NUM2
    BRA LOOP
    LOAD ORG
    SUB NUM3
    STA REM
    END LDA Q
    OUT Q
    LDA REM
    OUT REM
    HLT
    NUM1    DAT
    NUM2    DAT
    ORG     DAT
    Q       DAT
    ONE     DAT 1
    TOTAL   DAT 
    NUM3    DAT
    REM     DAT

当我尝试在 LMC 模拟器中运行代码时,它不会产生结果,而是无限期地继续计算。我怎样才能让它工作?有一个更好的方法吗?任何帮助是极大的赞赏。

4

2 回答 2

1

有一个更好的方法吗?

你的方法是合乎逻辑的,但可能有点矫枉过正。只做除法,当你不能再从被除数中减去除数时停止,将同时产生商和余数。

例如,如果你想将 13 除以 4,然后从 13 中减去 4,得到 9,然后从 9 中减去 4,得到 5,然后从 5 中减去 4,得到 1,现在我们停止,因为 4 大于 1(我们不能减去没有消极)。商是我们能够减去 4 的次数(即 3 次),余数是停止后剩下的,这里是 1。


我怎样才能让它工作?

至于你的代码为什么会无限循环,很可能你只是在寻找精确的除法,使用BRZ. 您应该考虑BRP改为使用,这将允许非零余数。您应该在 LMC 调试器中单步执行,以查看为什么它在您希望的时候不停止。

于 2021-11-25T21:44:39.913 回答
1

你的程序有几个问题:

  • OUT不接受争论。它不应该OUT Q,而只是OUT。一个好的 LMC 模拟器应该会抱怨这一点。
  • LOOP被定义为标签两次。这是模棱两可的。一个好的 LMC 模拟器应该会抱怨这一点。
  • 在. BRA LOOP_ END这是死代码。
  • 循环只能在NUM1变为零时退出,但这可能永远不会发生。例如,如果您将 4 除以 5,则减法将产生负溢出,并且累加器不会为零(实际上它不是由语言定义的,它将具有的值)。而不是在BRZ那里使用,您应该使用BRP.
  • 的初始化Q取自邮箱 99,但假设您的程序不占用邮箱 99。这是真的,但最好为 a 使用标签DAT 0
  • 没问题,但第三条指令 ( LDA NUM1) 不是必需的,因为累加器已经具有该值。

您要实现的算法有点冗长。在您从第一个数字中减去第二个数字并且不可能再进行减法之后,您将已经有了余数(如果您做对了)。

您的算法还应该以不同的方式处理 0 除数:在这种情况下,可能会输出一些预定义的值来指示商未定义,例如 999。

这是您如何编写代码的方法。这是一个可运行的片段,其中包含一些您可以调整的示例输入:

#input: 19 5
          LDA zero       # initialise
          STA quotient
          INP
          STA remainder
          INP
          STA divisor
          BRZ error      # division by 0 is undefined
loop      LDA remainder
          SUB divisor
          BRP continue
end       LDA quotient   # output the results
          OUT
          LDA remainder
          OUT
          HLT
continue  STA remainder
          LDA quotient
          ADD one
          STA quotient
          BRA loop
error     LDA big     # output 999 twice to indicate error
          OUT
          OUT
          HLT
remainder DAT
divisor   DAT
quotient  DAT
zero      DAT 0
one       DAT 1
big       DAT 999


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

于 2021-11-25T23:00:04.783 回答