向LMC输入三个数,从大到小输出?

Input three numbers into the LMC and output them largest to smallest?

所以,我已经设法解决了大部分问题,但是如果输入值递增,我只能从大到小输出? first = 10,second = 20,third = 30。如果值不同,我将如何正确输出? (例如,5、1、3?)

这是我目前拥有的:

        INP
        STA first
        INP
        STA second 
        INP
        STA third
        SUB first
        BRP branch1 
        LDA second 
        STA third 
branch1 LDA third 
        SUB second
        BRP branch2 
        LDA first
        STA third 
branch2 LDA third 
        OUT
        LDA first
        SUB second
        BRP branch3
        LDA second
        OUT
branch3 LDA first
        OUT
        HLT
first   DAT
second DAT
third   DAT

我建议你为此编写C或伪代码。它只会是一两行左右,这会让你理清思路。

您的 pseudo/C 代码将包含 if-then-else 语句。这是高级 C 中的 if-then-else 模式,然后在低级 C 中重复。当您翻译 if-then-else 语句时,请遵循以下模式:

if ( <condition> ) {
    <then-part>
}
else {
    <else-part>
}

请注意,then 部分和 else 部分中只有一个应该 运行。

相同的控制结构,if-then-else,在汇编语言的 if-goto-label 风格中:

    if <condition> is false goto elsePart1;
    <then-part>
    goto endIf1;
elsePart1:
    <else-part>
endIf1:

我们首先要注意标签不执行——处理器看不到它们,因为它们在生成机器代码时被汇编器删除了。处理器只能看到&执行机器码指令,标签没有机器码。

以下是 if-then-else 在 if-goto-label 中的工作方式:当条件为假时,它将跳过 then-部分到 运行 else-部分。但在条件为真时,它不会分支并因此执行 then-part。 then 部分执行后我们需要跳过 else 部分 这就是无条件分支和 endIf1: 标签的原因如果转到标签版本 。 (如果没有那个无条件分支,它会 运行 then 部分之后的 else 部分,这会很糟糕。)同样重要的是,在 if-then-else 语句之后,程序 运行是下一条语句,不管它的 then-part 还是 else-part 都被触发了。

如果您有多个 if-then-else 语句,只需为其标签使用不同的编号即可。嵌套的 if-then-else 仍应遵循此模式——建议先翻译外部的,然后再翻译内部的,但其他顺序也可以。它也可以按程序顺序完成,但这使得遵循这些简单的模式变得更加困难。

一些问题:

  • 当你这样做时:

    LDA second
    STA third 
    

    ...您丢失了 third 的原始输入,因此不可能仍然产生正确的输出。在您执行 STA 的其他地方也会发生同样的情况。相反,您可以考虑 swap 值。通常你需要一个临时变量(一个额外的 DAT)。例如,如果您想将 secondthird 交换,则:

    LDA second
    STA temp
    LDA third
    STA second
    LDA temp
    STA third
    
  • 您从 firstthird 之间的比较开始,当您检测到 first 大于 third 时,您复制 secondthird。奇怪的是,你决定在这一点上涉及 second(对此你没有做出任何结论)。用 first 做点什么会更有意义。如果您将 swap firstthird 那么您将得到 first 现在保证不大于 [=13] 的“不变量” =],无论您是 分支 branch1 还是从上一条指令到达该标签。这是对输入进行排序的第一步。

  • 如果 BRP branch3 导致跳转至 branch3,您最终将只有 2 个输出而不是 3 个。None 三个 OUT 指令应该被跳过。或者你应该添加更多的 OUT 指令,这样在每个执行路径中总是恰好有 3 个被执行。

这是更正后的脚本,您可以在此处运行:

#input: 3 1 2
        INP
        STA first
        INP
        STA second 
        INP
        STA third
        SUB first
        BRP branch1
        LDA first   # don't deal with second, but with first
        STA temp    # use temp to perform swap first <--> third
        LDA third
        STA first
        LDA temp
        STA third
branch1 LDA third   # at this point we know first <= third
        SUB second
        BRP branch2 
        LDA second  # don't deal with first, but with second
        STA temp    # use temp to perform swap second <--> third
        LDA third
        STA second
        LDA temp
        STA third 
branch2 LDA third   # at this point we know first <= third && second <= third 
        OUT
        LDA first
        SUB second
        BRP branch3
        LDA second
        OUT
        LDA first   # We cannot use branch3 here, as there we still output second
        OUT
        HLT
branch3 LDA first
        OUT
        LDA second
        OUT
        HLT
first   DAT
second  DAT
third   DAT
temp    DAT

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