Программа 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