Программа Keil ARM7, которая ищет массив

Программа требует считывания элементов массива из 10 чисел, подсчета количества нулей в этом массиве и сохранения его в R7. Вот что я разработал до сих пор...

    AREA addition, CODE, READWRITE
    ENTRY
    LDR R0,=ARR
    MOV R1, #0        ; Loop Iterator
    MOV R2, #0        ; Array Index
    MOV R7, #0        ; Number Of Zeros In The Array

LOP CMP R1, #10
    BEQ EXT
    LDR R3, [R0]
    CMP R3, #0
    BEQ MOVE1
    B CNT

MOVE1 ADD R7, R7, #1
      B CNT

CNT ADD R2, R2, #4
    ADD R1, R1, #1
    B LOP

ARR DCD 3,-5,-1,0,10,0,4,-8,7,6
EXT

    END

Проблема в том, что он никогда не входит в MOVE1. Я действительно не могу понять, почему.

Заранее спасибо.

2 ответа

Решение

R0 никогда не изменяется, поэтому значение загружается в R3 никогда не меняется, поэтому тест для вашего цикла всегда получается одинаковым. (И вам не нужно B CNT после MOVE1, так как это следующая инструкция, в любом случае.)

Вы не используете R2 для индексации массива, поэтому сравниваете первое значение с нулем десять раз. Я не эксперт по ARM, но если вы хотите сделать это, вам придется использовать эквивалентный синтаксис LDR R3, [R0+R2].

На самом деле, зачем? Просто добавьте 4 к указателю (R0) вместо R2, и он всегда смотрит в нужное место.

Пара моментов:

BEQ MOVE1
B CNT

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

Не считать, считать вниз.

MOV R1, #10
...
SUB R1, #1
BNE LOP      ; Branches unless R1 is now zero

Вы также можете обнаружить, что LDR устанавливает нулевой флаг (я когда-либо сталкивался только с одним ассемблером, который не пробовал или не искал его), и поэтому нет необходимости фактически сравнивать его с нулем.

Когда вы работаете с ассемблером, вы должны научиться гибко мыслить. Более компактная версия вашего кода может быть:

ENTRY
    LDR  R0,=ARR
    MOV  R1, #10       ; Loop Iterator
    MOV  R7, #0        ; Number Of Zeros In The Array

LOP LDR  R3, [R0], #4  ; Get current number, adds 4 to R0 afterwards - points to next number
    CMP  R3, #0        ; Might not be necessary, see if it works without this
    BNE  CNT           ; Next loop if not zero

    ADD  R7, R7, #1    ; Add 1 to count then drop down

CNT SUBS R1, R1, #1   ; S suffix sets z flag (New one on me).
    BNE  LOP

ARR DCD 3,-5,-1,0,10,0,4,-8,7,6
EXT
Другие вопросы по тегам