【问题标题】:How to produce dividend and remainder in a little man computer program?如何在小人计算机程序中产生股息和余数?
【发布时间】:2022-01-04 02:23:25
【问题描述】:

我正在尝试编写一个 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 模拟器中运行代码时,它不会产生结果,而是无限期地继续计算。我怎样才能让它工作?有一个更好的方法吗?非常感谢任何帮助。

【问题讨论】:

    标签: assembly multiplication integer-division little-man-computer


    【解决方案1】:

    你的程序有几个问题:

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

    您要实现的算法有点冗长。在您从第一个数字中减去第二个数字并且无法再进行减法之后,您将拥有余数(如果您操作正确的话)。

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

    您可以通过以下方式编写代码。这是一个可运行的 sn-p,您可以调整一些示例输入:

    #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>

    【讨论】:

      【解决方案2】:

      有没有更好的方法来做到这一点?

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

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


      我怎样才能让它工作?

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-30
        • 1970-01-01
        相关资源
        最近更新 更多