如何在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。
答案 0 :(得分:3)
关于它背后的“数学”:它与十进制系统中的相同:
添加两位数字时,必须考虑两种情况。要么两者之和是一个新的单个数字(5 + 4 = 9),要么发生'溢出'而需要另一个数字(5 + 6 = 11)。请注意,对于n
个数字长度的任何两个数字(在任何基数中,可以是10,2,256或其他),两者之和总是低于最低值的两倍n+1
位数的长度;让i
和j
为数字(基数10),例如长度为1,即两者都在0
和9
之间,包括10
和n+1 = 2
。由于2 x 10
是长度ADD
的最小数量,因此其总和将始终低于ADD
。
当添加两个数字时,可能没有溢出或者可能正好溢出1.进位位存储上次算术运算的溢出;它是0或1。
因此,当添加两个4x 8位的数字(可以看作4位'基数256)时,第一次添加时不会考虑溢出,因此只有x = x + y + 0
; ADDC
可视为ADDC
的操作。然而,在第一次添加之后可能存在需要考虑的溢出,这通过使用x = x + y + carry
来完成; carry
代表x = x + y;
if ( carry == 1 ) {
error "The sum is too big for the datatype of x";
}
的操作,其中{{1}}只能是0或1,如上所述。添加完所有数字后,最后一次添加可能会再次导致溢出,这会在之后的进位中反映出来,并且可以评估它可能对数字范围的溢出做出反应,如:
{{1}}
答案 1 :(得分:3)
非常简单的操作。使用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操作码添加常量。例如,要向R18添加5:R19:
SUBI R18,-5
SBCI R19,-1 # This isn't intuitive, but needs to be -1, not zero
从R18减去5:R19:
SUBI R18,5
SBCI R19,0