Просто для цикла и суммы

Я пытаюсь выучить язык ассемблера HCS12, но примеров в интернете недостаточно. Я пытался написать код, но безуспешно. Я застрял. Это не совсем домашнее задание. Может кто-нибудь написать это на ассемблере HCS12 с комментариями? Я хочу код, потому что действительно хочу читать его шаг за шагом. Кстати, есть ли другой способ определить массив?

;The array arr will be located at $1500 and the contents {2, 5, 6, 16, 100, 29, 60}
sum = 0;
for i = 0 : 6
    x = arr[i];
    if( x < 50 )
            sum = sum + x
end

Моя попытка:

Entry:

            ;2,5,6,16,100,39,60               
            LDAA #2
            STAA $1500
            LDAA #5
            STAA $1501
            LDAA #6
            STAA $1502
            LDAA #16
            STAA $1503
            LDAA #100
            STAA $1504
            LDAA #39
            STAA $1505
            LDAA #60
            STAA $1506

            CLRA  ; 0 in accumulator A
            CLRB  ; 0 in accumulator B
            ADDB COUNT ; B accumulator has 6

loop:       

            ;LDAA 1, X+ ; 1500 should be x because it should increase up to 0 from 6
                        ; A accumulator has 2 now
            BLO 50; number less than 50
            ;ADDA 


            DECB
            BNE loop

1 ответ

Ниже приведен один из возможных способов реализации вашего конкретного цикла FOR.

Это в основном для HC11, который на уровне источника совместим с HCS12, поэтому он также должен правильно собираться для HCS12. Однако HCS12 имеет некоторые дополнительные инструкции и режимы адресации (например, индексированное автоинкремент), которые могут сделать код немного короче и даже более читабельным. Во всяком случае, я на самом деле не пробовал это, но все должно быть в порядке.

Кстати, ваш код показывает, что у вас есть некоторое фундаментальное непонимание определенных инструкций. Например, BLO 50 не означает ветвление, если аккумулятор ниже 50. Это означает проверку соответствующих флагов CCR (регистр кода состояния), которые должны быть уже установлены какой-либо предыдущей инструкцией, и переход к адресу 50 (очевидно, не то, что вы предполагали), если значение меньше чем цель. Чтобы сравнить регистр со значением или некоторым местом в памяти, вы должны использовать CMPx инструкции (например, CMPA).

;The array arr will be located at $1500 and the contents {2, 5, 6, 16, 100, 29, 60}

                    org       $1500               ;(somewhere in ROM)
arr                 fcb       2,5,6,16,100,29,60  ;as bytes (use dw if words)

                    org       $100                ;wherever your RAM is
;sum = 0;
sum                 rmb       2                   ;16-bit sum

                    org       $8000               ;wherever you ROM is
;for i = 0 : 6
                    clrb                          ;B is your loop counter (i)
                    stb       sum                 ;initialize sum to zero (MSB)
                    stb       sum+1               ;         -//-          (LSB)
ForLoop             cmpb      #6                  ;compare against terminating value
                    bhi       ForEnd              ;if above, exit FOR loop
;    x = arr[i];
                    ldx       #arr                ;register X now points to array
                    abx                           ;add offset to array element (byte size assumed)
                    ldaa      ,x                  ;A is your target variable (x)
;;;;;;;;;;;;;;;;;;; ldaa      b,x                 ;HCS12 only version (for the above two HC11-compatible lines)
                    inx                           ;X points to next value for next iteration
;;;;;;;;;;;;;;;;;;; ldaa      1,x+                ;HCS12 only version (for the above two HC11-compatible lines)
;    if( x < 50 )
                    cmpa      #50
                    bhs       EndIf
;            sum = sum + x
                    adda      sum+1
                    staa      sum+1
                    ldaa      sum
                    adca      #0
                    staa      sum
EndIf
                    incb                          ;(implied i = i + 1 at end of loop)
                    bra       ForLoop
;end
ForEnd

Выше предполагается, что ваш массив является постоянным, поэтому он находится где-то в ПЗУ во время сборки. Если ваш массив динамический, он должен находиться в оперативной памяти, и вам нужно будет использовать код для его загрузки (аналогично тому, как вы это делали). Однако для эффективности обычно используется цикл при загрузке (копировании) нескольких значений из одного места в другое. Это и более читабельно, и более эффективно с точки зрения необходимой памяти кода.

Надеюсь это поможет.

Отредактировано: забыл инициализировать SUM в ноль.

Отредактировано: в отличие от HC08, CLRA в HC11 очищает Carry, поэтому последовательность CLRA, ADCA неправильно. Заменено на правильное: LDAA, ADCA #0

Другие вопросы по тегам