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 はレジスタ D1 に即値 0xA0 を追加します。おそらく、代わりに直接追加する必要があります。

        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

それでもオーバーフローが発生することに注意してください。あなたがそこで何をしているのかわからないので、あなたにそれを理解させます。また、RETURN への無条件分岐を使用しているため、CLR が実行されることはなく、SUM が 0 を返すことは不可能であることに注意してください。

この変更の後、RTS で戻ることによって NoV をサブルーチンのように動作するように変更することが重要です。D1 の整数値を文字列として表示するための TRAP 値があることに注意してください。これはおそらくあなたが望むものです:

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

この時点で、数値を追加して結果を表示することができますが、常にオーバーフローが表示されます。サブルーチンを修正してから、プログラムのロジック フローを再評価します。

于 2012-04-14T00:26:47.257 に答える