У меня возникли проблемы с работой этой подпрограммы добавления

Я пишу дополнительную программу для моего класса языка ассемблера в 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

person TheTrain    schedule 14.04.2012    source источник


Ответы (1)


Поток ÿ происходит отсюда:

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

Еще пара вещей:

Вы загружаете МАССИВ в A0 в начале каждого цикла в SUM. Вероятно, вы должны сделать это перед циклом:

SUB     LEA         ARRAY,A0
        BSR         SUM

Внутри SUM игнорируйте то, что я сказал, и используйте косвенную адресацию. Это возьмет фактическое значение из массива и добавит его в аккумулятор (я предполагаю, что это D1):

SUM     ADD.W       (A0)+,D1

NoV выглядит так, будто отображает текущее значение аккумулятора, верно? Вы используете для этого условную ветвь: хорошо, вы, вероятно, хотите, чтобы она отображалась только после того, как вы закончили суммирование. Но BVC на самом деле не является филиалом! Это не сохранит указатель возврата. Вместо этого я бы переместил его в часть SUM, которая выполняется после того, как счетчик достигает 0, и я бы использовал 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.

После этого изменения важно изменить NoV, чтобы он действовал как подпрограмма, возвращаясь с RTS. Обратите внимание, что есть значение TRAP для отображения целочисленного значения D1 в виде строки, что, вероятно, вам и нужно:

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

На данный момент я могу заставить его добавлять числа и отображать результат, но он всегда показывает переполнение. Исправьте свои подпрограммы, затем переоцените логический поток вашей программы.

person Jeff    schedule 14.04.2012