Добавляем номера в сборку AVR

Как это сделать в сборке AVR?

У меня есть 2 номера (с прямым порядком байтов) в разных регистрах.

# Number 1
LDI R16 0x…
LDI R17 0x…
LDI R18 0x…
LDI R19 0x…
# Number 2
LDI R20 0x…
LDI R21 0x…
LDI R22 0x…
LDI R23 0x…

Я хочу сложить их вместе и сохранить результат в R20 - R23.


person Droidik    schedule 04.06.2012    source источник
comment
Вы пользовались Google? Если нет, тогда StackOverflow — еще не то место, где можно спрашивать. (Если стандартный метод не работает, следует указать это.)   -  person huon    schedule 04.06.2012
comment
Я попробовал Google ;-) Но не берите на себя ответственность за добавление большого количества регистраций. - Должно быть что-то вроде этого? ADD R20,R16.... ADC R21,R17.... и так далее?   -  person Droidik    schedule 04.06.2012
comment
Да, именно так ты и делаешь :)   -  person JimmyB    schedule 05.06.2012


Ответы (2)


Что касается «математики», стоящей за этим: это точно так же, как в десятичной системе:

При сложении двух однозначных чисел необходимо учитывать два случая. Либо сумма этих двух цифр представляет собой новое однозначное число (5+4 = 9), либо происходит «переполнение» и требуется другая цифра (5+6 = 11). Обратите внимание, что для любых двух чисел (в любой системе счисления, будь то 10, 2, 256 и т. д.) длиной n цифр сумма этих двух чисел всегда будет меньше удвоенного наименьшего числа из n+1 цифр. длина; пусть i и j будут числами (с основанием 10), например, длиной 1, то есть оба находятся между 0 и 9 включительно. Поскольку 10 — наименьшее число длины n+1 = 2, их сумма всегда будет меньше 2 x 10.

При добавлении двух чисел может не быть переполнения или может быть переполнение ровно 1. Бит переноса сохраняет это переполнение из последней арифметической операции; это либо 0, либо 1.

Таким образом, при добавлении двух ваших чисел 4x 8 бит каждое (которые можно рассматривать как 4 «цифры» с основанием 256) для первого добавления не будет учитываться переполнение, следовательно, только ADD; ADD можно рассматривать как операцию для x = x + y + 0. Однако после первого добавления может возникнуть переполнение, которое необходимо учитывать, что делается с помощью ADDC; ADDC представляет операцию x = x + y + carry, где carry может быть только 0 или 1, как указано выше. После того, как все цифры были добавлены, последнее добавление могло снова вызвать переполнение, которое впоследствии будет отражено в бите переноса и может быть оценено, чтобы, возможно, отреагировать на переполнение диапазона номеров, например:

x = x + y;

if ( carry == 1 ) {
  error "The sum is too big for the datatype of x";
}
person JimmyB    schedule 05.06.2012
comment
в C вы можете написать unsigned sum = x + y; unsigned carry = (sum < x); (работает только для значений без знака). Некоторые компиляторы будут использовать результат выполнения инструкции add вместо фактического сравнения при ее компиляции. - person Peter Cordes; 14.11.2017

Довольно простая операция. Используйте add для первой операции и add-with-carry для последующих добавлений.

# Number 1
LDI R16 0x…
LDI R17 0x…
LDI R18 0x…
LDI R19 0x…
# Number 2
LDI R20 0x…
LDI R21 0x…
LDI R22 0x…
LDI R23 0x…
# Add LSB of 1 and 2, result will be in R20
ADD R20,R16
# Add remaining bytes using the add-with-carry operation
ADC R21,R17
ADC R22,R18
ADC R23,R19 # MSB

Результат перезапишет значение в R20:R23.

Я знаю, что вы просто загружали константы в регистры в качестве примера, но не забывайте, что вы можете добавлять константы, используя коды операций subi и sbci. Например, чтобы добавить 5 к R18:R19:

SUBI R18,-5
SBCI R19,-1 # This isn't intuitive, but needs to be -1, not zero

Чтобы вычесть 5 из R18:R19:

SUBI R18,5
SBCI R19,0 
person Bradley Snyder    schedule 13.06.2012