【问题标题】:Sieve of Eratosthenes little man computer埃拉托色尼筛小人电脑
【发布时间】:2017-01-27 10:43:01
【问题描述】:

有人可以帮我理解,为什么只有在 input

    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/ 来尝试运行这个程序

【问题讨论】:

  • 这是什么类型的问题?什么编程领域?
  • 小人电脑的简单汇编代码。这仅在输入小于 69 时有效,我不知道为什么
  • 你从哪里得到这个代码?我相信这是对我编写的代码的改编,有一些非常小的改编。您可以在我的博客上看到指向我的原始代码的链接:paulhankin.github.io/LittleManComputer。我个人认为我的 LMC 模拟器比你现在使用的那个更好,但也许我有偏见:)
  • 无论输入如何,您所做的编辑都会使其无法正常工作。

标签: sieve-of-eratosthenes little-man-computer


【解决方案1】:

由于 LMC 可用的内存有限,程序在输入值 69 以上时崩溃。可能的最高地址(邮箱)是 99。

此代码使用筛子的内存空间,筛子需要与您提供给它的输入一样大。筛子的内存从邮箱 31 开始,该邮箱在代码中的标签 LDINSSTINS 处定义:531 表示 LDA 31,其中 31 是邮箱地址。同样,331 表示STA 31。这定义了筛子的最大尺寸:31 到 99 总共有 69 个邮箱可以为筛子服务。

指令STA WRINS 将动态更改标签WRINS 处的代码,以便在筛子数组中写入一个值。写入的动态操作码是 300 + 31 + [一些动态偏移]。 300 代表STA,而 31 是筛阵列开始的位置。现在当偏移量为69以上时,这条指令就变成了400以上,不再代表STA指令,而是未定义的操作码。

你可以在下面的 sn-p 中运行你的代码,当你给它 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 实现总是在该大小附近有限制,这取决于您可以使代码多么简洁——为数组留出空间。

代码备注

以上内容回答了您的问题,但您的代码需要做一些 cmet。

你好像修改了一个已有的程序,快速添加了一些初步的指令输出2和3,但是你没有按照这个调整筛内存的起始地址。在您当前的程序中,地址 31 指向带有BRA WRITELOOP 的行(邮箱),这不是您的目的。 READINS处的动态代码第一次执行时,该位置有指令LDA INPUTINPUT,对应地址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>

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多