有人可以帮助我理解,为什么只有在输入< 69时才能工作? 我正在使用Little Man Computer的简单汇编代码
INP
STA INPUT
LDA C
OUT
ADD ONE
OUT
LOOP LDA A \\ first loop
ADD ONE
STA A
SUB INPUT
BRP END
LDA A
ADD LDINS
STA READINS
READINS DAT
BRZ PRIME
BRA LOOP
PRIME LDA A
OUT
STA B
WRITELOOP LDA B \\ second loop
SUB INPUT
BRP LOOP
LDA B \\ at this moment program breakdown when input is more than 69
ADD STINS
STA WRINS
LDA A
WRINS DAT
LDA B
ADD A
STA B
BRA WRITELOOP
END HLT
INPUT DAT 0
LDINS DAT 531 \\ this is working, but i think i might do a better code
STINS DAT 331
A DAT 1
ONE DAT 1
B DAT
C DAT 2
我使用http://peterhigginson.co.uk/lmc/来尝试使用此程序
答案 0 :(得分:0)
由于LMC可用的内存有限,程序在输入值69以上崩溃。最高可能的地址(邮箱)是99。
此代码使用筛子的存储空间,该空间需要与您为其输入的输入一样大。筛子的内存始于邮箱31,邮箱31在代码中的标签LDINS
和STINS
上定义:531表示LDA 31
,其中31是邮箱地址。类似地331表示STA 31
。这定义了筛子的最大尺寸:31到99个筛子总共可以容纳69个邮箱。
指令STA WRINS
将动态更改标签WRINS
上的代码,以便将其值写入sieve数组。写入的动态操作码为300 + 31 + [某些动态偏移量]。 300代表STA
,而31是筛分阵列的起始位置。现在,当偏移量为69或更大时,此指令将变为400或更大,不再代表STA
指令,而是未定义的操作码。
您可以在下面的代码段中运行您的代码,当将其输入70时,您将看到该代码停滞在该指令上,表明操作码无效:
#input: 70
INP
STA INPUT
LDA C
OUT
ADD ONE
OUT
LOOP LDA A \\ first loop
ADD ONE
STA A
SUB INPUT
BRP END
LDA A
ADD LDINS
STA READINS
READINS DAT
BRZ PRIME
BRA LOOP
PRIME LDA A
OUT
STA B
WRITELOOP LDA B \\ second loop
SUB INPUT
BRP LOOP
LDA B \\ at this moment program breakdown when input is more than 69
ADD STINS
STA WRINS
LDA A
WRINS DAT
LDA B
ADD A
STA B
BRA WRITELOOP
END HLT
INPUT DAT 0
LDINS DAT 531 \\ this is working, but i think i might do a better code
STINS DAT 331
A DAT 1
ONE DAT 1
B DAT
C DAT 2
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.76/lmc.js"></script>
因此,结论是,此行为实际上不是程序中的错误,而是LMC的内存限制。 LMC的Eratosthenes筛网的实现始终会在该大小附近有所限制,具体取决于您可以使代码简明扼要-为数组留出空间。
以上内容回答了您的问题,但是对于您的代码有一些注释。
似乎您修改了一个现有程序,添加了一些初步指令以快速输出2和3,但是您没有按照相应的要求调整筛网存储器的起始地址。在当前程序中,地址31指向带有BRA WRITELOOP
的行(邮箱),这不是您的目的。第一次执行READINS
处的动态代码时,该位置的指令LDA INPUT
为INPUT
,对应于地址33。
这也是程序不输出5作为质数的原因。该程序实际上应该指出其可用内存的余量,而不是已经使用的数据。为了节省空间,您可以让筛子地址以标签ONE
开头,因为从未访问过筛子的前两个条目。
我认为使用标签和助记符代替硬编码的操作码和地址也更好,因此避免使用诸如331和531之类的含糊不清的东西(如所示),并且在修改程序时容易出错。 >
此外,您应该明确列出程序将使用的DAT
条目。
这里是更正后的版本,显然仍然对输入有限制:67是您输入的最大值而不会破坏代码。
#input: 67
INP
STA INPUT
LOOP LDA A \\ first loop
ADD ONE
STA A
SUB INPUT
BRP END
LDA A
ADD LDINS
STA READINS
READINS DAT
BRZ PRIME
BRA LOOP
PRIME LDA A
OUT
STA B
WRITELOOP LDA B \\ second loop
SUB INPUT
BRP LOOP
LDA B
ADD STINS
STA WRINS
LDA A
WRINS DAT
LDA B
ADD A
STA B
BRA WRITELOOP
END HLT
INPUT DAT
LDINS LDA ONE
STINS STA ONE
A DAT 1
ONE DAT 1 // also the start of the sieve
B DAT
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.76/lmc.js"></script>