assembly 如何正确重置LMC中的NEG标志,而无需存储该变量,然后再次加载它?

vfhzx4xs  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(76)

我给定的任务是找到平均值的总和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比预期的少一个。
我的问题是,你如何解决这个问题(用最少的附加指令)?

soat7uwm

soat7uwm1#

实际上,对于LMC,在SUB之后立即执行ADD是不好的,因为这会影响累加器上的负标志 * 和 *。(取决于模拟器),SUB之后的累加器值也没有定义,尽管大多数LMC模拟器将使用模运算(或将允许累加器实际上具有负值),但不能依赖于此行为。
解决方法是先用BRP检查SUB是否在零以下溢出,然后--如果溢出了--在减法完成之前 * 用原始值再次加载累加器。这是最可靠的方法(就代码的可移植性而言)。
其他一些评论:

  • BRZ紧跟在BRP之后时,BRZ几乎没有意义,因为当累加器的值为零时,后者也将分支。
  • 标签的名称out是不明确的:一些LMC模拟器可能会将其解释为指令OUT,并且无法解析程序。
  • 名称rtxycnt,.等不是很有描述性。我不会重复任何东西,只是使用更长的标签:这将提高代码的可读性。
  • 我不会在除法过程中重复将余数加到当前值上(在x中),因为在大多数情况下余数将为0。您可以在执行最后一次减法的情况下(y情况)这样做,然后将其重置为零,并执行除法循环的一次迭代(因为现在当前值可能在3和5之间)。
  • 如果将xy的块交换,则可以保存一条BR指令。

这里是修改后的代码-你可以在这里运行它:

#input: 4 4 2
           LDA zero
           STO remainder
           STO average
           LDA three
           STO inputcount
getnext    IN
           STO value
divide     LDA value
           SUB three
           BRP positive
           LDA remainder # ignore the subtraction of 3
           BRZ continue  # branch if no remainder
           ADD value # now we have no problem with NEG flag
           STO value # remainder is added
           LDA zero
           STO remainder
           BR  divide # repeat one more time
positive   STO value
           LDA average
           ADD one
           STO average
           BR  divide
continue   LDA value
           STO remainder
           LDA inputcount
           SUB one
           STO inputcount
           BRZ output
           BR  getnext
output     LDA average
           OUT
           HLT
value      DAT 0
average    DAT 0
inputcount DAT 3
remainder  DAT 0
zero       DAT 0
one        DAT 1
three      DAT 3


<script src="https://cdn.jsdelivr.net/gh/trincot/[email protected]/lmc.js"></script>

字符串

相关问题