1

我怎样才能在 AVR 组装中做到这一点?

我在不同的 reg 中有 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。

4

2 回答 2

3

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

添加两个个位数时,必须考虑两种情况。两者之和是一个新的个位数 (5+4 = 9),或者发生“溢出”并且需要另一个数字 (5+6 = 11)。请注意,对于数字长度的任何两个数字(以任何基数,无论是 10、2、256 还是其他数字),n两者的总和将始终小于最小n+1数字长度的两倍;设ij为例如长度为 1 的数字(以 10 为底),也就是说,两者都在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";
}
于 2012-06-05T09:22:04.783 回答
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 操作码添加常量。例如,要将 5 添加到 R18:R19:

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

从 R18:R19 中减去 5:

SUBI R18,5
SBCI R19,0 
于 2012-06-13T03:03:09.470 回答