在AVR程序集中添加数字

时间:2012-06-04 10:27:54

标签: assembly 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。

2 个答案:

答案 0 :(得分:3)

关于它背后的“数学”:它与十进制系统中的相同:

添加两位数字时,必须考虑两种情况。要么两者之和是一个新的单个数字(5 + 4 = 9),要么发生'溢出'而需要另一个数字(5 + 6 = 11)。请注意,对于n个数字长度的任何两个数字(在任何基数中,可以是10,2,256或其他),两者之和总是低于最低值的两倍n+1位数的长度;让ij为数字(基数10),例如长度为1,即两者都在09之间,包括10n+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