3

我正在用 Easy68k 为我的汇编语言类编写一个附加程序,但我一直遇到同样的问题。每当我运行该程序时,它允许我输入最多 10 个数字(分配给我的数组的大小),然后它输出消息说它正在计算,但我只是得到一个无休止的 y 与变音符号的打印输出。您可以立即看到我的程序导致它执行此操作的任何问题?

我已经搜索了子例程的语法,因为我很肯定那是我做错了,但我找不到任何东西。

ORG $2000
ARRAY   DS.W    10
ZDONE       DC.W    'Enter values. Zero when done.'
FULL        DC.W    'That is all the input allowed. Calculating sum now...'
OERROR      DC.W    'The values you entered caused an overflow condition.'
REPEAT      DC.W    'Do you want to repeat? [0=No, 1=Yes].'

START       ORG     $2800

MAIN    LEA         ZDONE,A1
        MOVE.B      #14,D0          ;
        TRAP        #15
        LEA         ARRAY,A0

        MOVE.B      #0,D3
INPUT   MOVE.B      #4,D0
        TRAP        #15
        MOVE.W      D1,(A0)+
        BEQ         SUB
        ADD.B       #1,D3
        CMPA        #$2012,A0
        BNE         INPUT
        LEA         FULL,A1
        MOVE.B      #14,D0           ; Outputs the FULL string
        TRAP        #15

SUB     SUB.W       A0,A0
        BSR         SUM              ; Begins to calculate sum

        CMP         #1,D0
        BNE         NoV
        LEA         OERROR,A1
        MOVE.B      #14,D0
        TRAP        #15
        BRA         AGAIN

NoV     LEA         $D1,A1
        MOVE.B      #14,D0
        TRAP        #15

AGAIN   LEA         REPEAT,A1
        MOVE.B      #14,D0
        TRAP        #15
        MOVE.B      #4,D0
        TRAP        #15
        MOVE.B      #1,D0
        CMP.B       D0,D1
        BEQ         START
        STOP        #$3800

        ORG         $3800        
SUM     LEA         ARRAY,A0
        ADD.W       #$A0,D1
        BVC         NoV
        SUB.B       #1,D3
        BNE         SUM
        MOVE.B      #1,D0
        BRA         RETURN
        CLR.B       D0
RETURN  RTS
        END         START
4

1 回答 1

2

ÿ的洪水来自这里:

NoV     LEA         $D1,A1
        MOVE.B      #14,D0
        TRAP        #15

您正在将0xD1的立即值加载到 A1 中。这就是 $ 的用途:它意味着立即寻址。调试器在这里很有用:如果您将程序运行到 MOVE.B 行,您将看到 A1 的值为 0x000000D1。这是使用 TRAP 打印的字符串的地址,对吗?0x000000D1 的内存中有什么?这是未定义的;在这种情况下,模拟器将内存初始化为 0xFF,对应于 ÿ 字符。

这可能是错误的:

SUB     SUB.W       A0,A0

您从 A0 中减去 A0,实际上将 A0 设置为 0。

我怀疑这也是错误的:

SUM     LEA         ARRAY,A0
        ADD.W       #$A0,D1

ADD 将立即值0xA0 添加到寄存器 D1。您可能想要直接添加:

        ADD.W       A0,D1

还有几件事:

您在 SUM 中的每个循环开始时将 ARRAY 加载到 A0 中。您可能应该在循环之前执行此操作:

SUB     LEA         ARRAY,A0
        BSR         SUM

在 SUM 内部,忽略我所说的并使用间接寻址。这将从数组中获取实际值并将其添加到累加器中(我假设这是 D1):

SUM     ADD.W       (A0)+,D1

NoV 看起来像是在显示累加器的当前值,对吧?您正在使用它的条件分支:好的,您可能只希望它在完成求和后显示。但 BVC 实际上并不是一个子分支!它不会保存返回指针。相反,我会将其移至计数器达到 0 后执行的 SUM 部分,并且我将使用 BSR:

SUM     ADD.W       (A0)+,D1
        SUB.B       #1,D3
        BNE         SUM
        BSR         NoV
        MOVE.B      #1,D0
        BRA         RETURN
        CLR.B       D0
RETURN  RTS

请注意,您仍然会得到溢出的东西。我不明白你在做什么,所以我会让你弄清楚。另请注意,由于您使用无条件分支返回,CLR 将永远不会被执行,因此 SUM 不可能返回 0。

在此更改之后,重要的是通过返回 RTS 将 NoV 修改为像子例程一样。请注意,有一个 TRAP 值用于将 D1 的整数值显示为字符串,这可能是您想要的:

NoV     MOVE.B      #3,D0
        TRAP        #15
        RTS

此时我可以让它添加数字并显示结果,但它总是显示溢出的东西。修复您的子程序,然后重新评估程序的逻辑流程。

于 2012-04-14T00:26:47.257 回答