0

我正在尝试创建一个循环,如果给定的数字是奇数或偶数(Par),它将打印。当累加器值为-1时如何分支循环?

START   INP // int(input(""))
        STA n // n =
LOOP    LDA n //
        BRZ END // while n !=0:
        SUB En // n - 1 
        STA n // n = 
        INP // int(input(""))
        ADD sum //
        STA sum //
        BRA LOOP //
END     LDA sum
        OUT
        BRP PO
PO      LDA sum
        BRZ EXIT
        LDA sum
        SUB TO
        STA sum
        BRA PO
ODDE    LDA O
        OTC
        LDA D
        OTC
        LDA D
        OTC
        LDA E
        OTC
O       DAT 79
D       DAT 68
E       DAT 69
        HLT
EXIT    BRP PAR
        HLT
PAR     LDA P
        OTC
        LDA A
        OTC
        LDA R
        OTC 
P       DAT 80
A       DAT 65
R       DAT 82
        HLT
TO      DAT 2
n       DAT 0
sum     DAT 0
En      DAT 1
Par     DAT -1
4

1 回答 1

0

当累加器值为-1时如何分支循环?

LMC 使用 0 到 999 之间的值定义邮箱。它们不能为负数。即使您可以从较小的值中减去较大的值,累加器的值也是未定义的。根据维基百科

SUBTRACT[...] 累加器的动作没有为导致负结果的减法指令定义 - 但是,将设置一个负标志,以便可以正确使用 7xx (BRZ) 和 8xx (BRP)。

因此,可靠地检测负值的唯一方法是使用BRP: 该分支指令将跳转到提供的目标地址,除非最近的减法设置了负标志。

代码审查

您的代码中存在以下问题:

  • Par DAT -1:如上所述,您不能将 -1 存储在 LMC 邮箱中。邮箱只能存储 000 到 999 之间的值。

  • Parvs PAR:您有两个仅在大小写上有所不同的标签。LMC 实现通常不区分大小写,因此这会使这两个标签相同。最好使用完全不同的标签。

  • BRP PO:标签PO指向下一条指令,因此这意味着代码执行将始终在该指令处继续,无论您是否分支。它使该指令无用。

  • O DAT 79: 这一行出现在一组以 . 结尾的指令之后OTC。如果执行了该代码,它将运行到这一DAT行。这可能导致未定义的行为。你不希望这种情况发生。因此,请确保DAT邮箱不受代码执行的影响。HLT在块之前添加一个DAT以避免它们像代码一样被执行。您在 有类似的问题P DAT 80

  • BRZ EXIT: 在EXIT地址处,你有一个BRP,但由于你只能在累加器为零时到达那里,所以不会设置负标志,因此总是BRP会分支。请注意,当未设置否定标志时分支。BRP

  • ODDE: 这个标签永远不会被引用,并且那个代码块永远不会被执行。您可以考虑将BRA出现在其前面的 -- 更改为BRP. 然后,当最后一次减法导致负结果(在您的情况下实际上是 -1,但累加器未定义)时,执行将失败。

如果你纠正了所有这些问题,你将得到一个非常接近这个工作版本的实现

于 2020-10-21T12:03:26.410 回答