Положительный, отрицательный и ноль (сборка) - PullRequest
0 голосов
/ 21 июня 2020

Я программирую старый MCU (68hc11), я пытаюсь перейти с языка C на код сборки с помощью инструкций 68hc11.

Я хочу написать программу на сборке, которая считает количество ПОЛОЖИТЕЛЬНЫХ, ОТРИЦАТЕЛЬНЫХ и НУЛЕВЫХ значений, которые существуют внутри данного массива. ОБРАТИТЕ ВНИМАНИЕ, что все значения внутри ARRAY могут быть либо положительными, либо отрицательными, либо нулями, понимаете? Поэтому я должен определить размер переменных, которые будут правильно хранить количество.

ПРИМЕЧАНИЕ. Конец массива: ARRAY + QUANTITY-1

Array: содержит случайные значения

КОЛИЧЕСТВО: представляют наибольшее количество элементов, которое может содержать МАССИВ

Я написал эту программу в C:

int A[15], pos, neg, nul, i;

[...]

pos = 0;
neg = 0;
nul = 0;

for (i = 0; i < 15; i++) {
    if (A[i] > 0) {
        pos++;
    }
    if (A[i] < 0) {
        neg++;
    }
    if (A[i] == 0) {
        nul++;
    }
}

Теперь я хочу перевести это, но в сборке (Я ЗАСТРЕЛ ЗДЕСЬ, я не получаю то, что хочу)

RWM         EQU $0
ROM         EQU   $C000
VRESET      EQU   $FFFE

QUANTITY    EQU 800 ;MEANS THE MAXIMUM AMOUNT OF VALUES THAT THE ARRAY WILL CONTAIN

            ORG RWM

POSITIVE        RMB 2
NEGATIVE        RMB 2
ZEROS           RMB 2

            ORG ROM
START:
            CLRA
            CLRB
            CLR POSITIVE
            CLR ZEROS
            CLR NEGATIVE
            LDY #ARRAY
            
LOOP
            CPY #(ARRAY+QUANTITY-1)

            BHI END
            LDD 0,Y
            INY
            BLT NEGATIVE_NUMBER
            BEQ ZERO_NUMBER
            BGE POSITIVE_NUMBER
            
            
NEGATIVE_NUMBER     INC NEGATIVE
                        BRA LOOP
                        
POSITIVE_NUMBER     INC POSITIVE
                        BRA LOOP
                        
ZERO_NUMBER         INC ZEROS
                        BRA LOOP
                        

END         BRA END

ARRAY       DW    78,554,-44,-4,2547,0,-3,0,1,7,8,

        ORG VRESET
        DW  START

Что не так с моим кодом?

EDIT:

ERROR

RWM         EQU $0
ROM         EQU   $C000
VRESET      EQU   $FFFE

QUANTITY    EQU 800 ;MEANS THE MAXIMUM AMOUNT OF VALUES THAT THE ARRAY WILL CONTAIN

            ORG RWM

POSITIVE        RMB 2
NEGATIVE        RMB 2
ZEROS           RMB 2

            ORG ROM
START:
            CLRA
            CLRB
            CLR POSITIVE
            CLR ZEROS
            CLR NEGATIVE
            LDY #(ARRAY-2)
            
LOOP
             INY
         INY
             CPY #(ARRAY+2*QUANTITY-1)
         BHI END
         LDD 0,Y
         BLT NEGATIVE_NUMBER
                 BEQ ZERO_NUMBER
                 BGE POSITIVE_NUMBER
            
            
NEGATIVE_NUMBER     INC NEGATIVE
                        BRA LOOP
                        
POSITIVE_NUMBER     INC POSITIVE
                        BRA LOOP
                        
ZERO_NUMBER         INC ZEROS
                        BRA LOOP
                        

END         BRA END

ARRAY       DW    78,554,-44,-4,2547,0,-3,0,1,7,8,

        ORG VRESET
        DW  START

I got this output (not sure about it)

возраст

1 Ответ

2 голосов
/ 21 июня 2020

Что не так с моим кодом?

Я только бегло просмотрел вашу программу, поэтому мой ответ может быть неправильным:

LDD 0,Y

Очевидно, вы работаете с 16-битными числами. В противном случае вы использовали бы LDA или LDB вместо LDD.

CPY #(ARRAY+QUANTITY-1)

Это было бы правильно, если QUANTITY - размер массива в байтах (например, 30 в случае int A[15]).

Если QUANTITY - это количество элементов, и вы работаете с 16-битными числами, вам нужно умножить на два:

CPY #(ARRAY+2*QUANTITY-1)
INY

И снова это будет работать для 8-битных элементов. Для 16-битных элементов вы должны добавить два к каждому элементу или увеличить Y дважды:

INY
INY
INY
BLT NEGATIVE_NUMBER

Инструкция INY изменит нулевой флаг и поэтому влияйте на инструкции BLT, BGE и BEQ. Вы не можете использовать INY между LDD и инструкциями ветвления.

BLT ...
BEQ ...
BGE ...

На самом деле это не ошибка, но инструкция BGE всегда будет ветвиться. Вы можете поместить числовой код POSITIVE_NUMBER после инструкции BEQ и удалить инструкцию BGE.

EDIT

Я не понимаю эта часть: INY, за которой следует Bxx

Я думал о трех разных способах сделать это. Самый простой вариант:

    LDY #(ARRAY-2)  ; Because we'll do INY twice right now
LOOP
    INY
    INY
    CPY #(ARRAY+2*QUANTITY-1)
    BHI END
    LDD 0,Y
    BLT NEGATIVE_NUMBER
    ...
...