我给定的任务是找到平均值的总和3输入四舍五入下使用LMC.我有以下代码:
LDA zro
STO r
STO cnt
LDA t
STO abc
lp IN
STO a
div LDA a
SUB t
ADD r
BRP x
BRZ x
BR y
x STO a
LDA cnt
ADD one
STO cnt
LDA zro
STO r
BR div
y ADD t
STO r
LDA abc
SUB one
STO abc
BRZ out
BR lp
out LDA cnt
OUT
HLT
a DAT 000
t DAT 003
cnt DAT 000
one DAT 001
abc DAT 003
r DAT 000
zro DAT 000
字符串
它适用于99%的输入0-999,保存一些像:
- 第一个月
生产2而不是3
596 165 2
个
生产253而不是254
148 574 2
个
生产240而不是241
对于这些输入,程序会产生一个比预期值小1的值,这是因为有一个bug,在加载新值之前NEG标志不会重置。
例如,在最后一个输入循环中,输入2(abc=1
),我们有a=2
; 2 - 3 = (999 NEG) + 2 = (1 NEG)
,它应该是1。但是NEG标志没有被重置,导致分支到错误的行(y
而不是x
)。因此cnt
比预期的少一个。
我的问题是,你如何解决这个问题(用最少的附加指令)?
1条答案
按热度按时间soat7uwm1#
实际上,对于LMC,在
SUB
之后立即执行ADD
是不好的,因为这会影响累加器上的负标志 * 和 *。(取决于模拟器),SUB
之后的累加器值也没有定义,尽管大多数LMC模拟器将使用模运算(或将允许累加器实际上具有负值),但不能依赖于此行为。解决方法是先用
BRP
检查SUB
是否在零以下溢出,然后--如果溢出了--在减法完成之前 * 用原始值再次加载累加器。这是最可靠的方法(就代码的可移植性而言)。其他一些评论:
BRZ
紧跟在BRP
之后时,BRZ
几乎没有意义,因为当累加器的值为零时,后者也将分支。out
是不明确的:一些LMC模拟器可能会将其解释为指令OUT
,并且无法解析程序。r
,t
,x
,y
,cnt
,.等不是很有描述性。我不会重复任何东西,只是使用更长的标签:这将提高代码的可读性。x
中),因为在大多数情况下余数将为0。您可以在执行最后一次减法的情况下(y
情况)这样做,然后将其重置为零,并执行除法循环的一次迭代(因为现在当前值可能在3和5之间)。x
和y
的块交换,则可以保存一条BR
指令。这里是修改后的代码-你可以在这里运行它:
字符串