负累加时分支

问题描述

我正在尝试创建一个循环,如果给定的数字为奇数或偶数(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

解决方法

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

LMC定义值为0到999之间的邮箱。它们不能为负。即使可以从较小的值中减去较大的值,累加器的值也仍未定义。根据{{​​3}}:

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

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

代码审查

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

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

  • ParPAR:您有两个标签,只是大小写不同。 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,但未定义累加器)时,执行将失败。

如果您纠正了所有这些问题,您将获得一个非常接近Wikipedia

的实现