用铅笔和纸回到小学。如果我想添加 1234 和 5678
1234
+ 5678
======
4+8 是 2 携带 1
1
1234
+ 5678
======
2
等等
00110 <-- carry bits
1234 <-- first operand
+ 5678 <-- second operand
======
6912
个位列上方的进位位是有效的,称为进位,离开最左侧列的进位位是进位。
如果我只有足够宽的纸张一次添加两列怎么办?
110
34
+ 78
======
12
我从较低的两组数字开始,我需要一个零作为进位。我得到一个带有进位的结果 12。
现在我将其取出,将其用作接下来两位数的进位。这个加法器我必须能够从之前的加法中取出一个进位并将其用作此加法的进位。
001
12
+ 56
====
69
当一切都说完了,我得到了 69 和 12,把它们放在一起我得到 6912,但不需要一个完整的 4 位数加法器就可以到达那里。您可以一直重复此操作,或者直到内存、寄存器或时钟周期用完为止。
avr 可能有其他解决问题的方法,但大多数处理器至少有两种形式的加法和两种形式的减法,以便您可以将加法器级联到您需要的宽度。检查 avr 的指令集,上面发生的事情应该会跳出来。
编辑:
AC 示例可能会有所帮助...(切换到十六进制)
unsigned int a,b,c,d,cin,cout,x,y;
a=0x12; b=0x34;
c=0x56; d=0x78;
x=b+d; //dont want a carry in or assume it is zero
cout=x&0x100;
if(cout) cin=1; else cin=0;
y=a+c+cin; //need the carry out on the prior add as the carry in here
x&=0xFF;
y&=0xFF;
printf("0x%02X%02X\n",y,x);
编辑2:
我希望这不是家庭作业...
ldi r20,0x12
ldi r21,0x34
ldi r22,0x56
ldi r23,0x78
add r21,r23
adc r20,r22
结果在 r20 高字节和 r21 低字节
如果您需要从 ram 读取有很多方法,这假设 16 位数字是小端
lds r0,0x100
lds r1,0x101
lds r2,0x102
lds r3,0x103
add r0,r2
adc r1,r3
r0 结果的下半部分, r1 上半部分。
或使用 x、y 或 z 指针寄存器之一
;put 0x0100 in Z
ldi r30,0x00
ldi r31,0x01
ld r0,z+
ld r1,z+
ld r2,z+
ld r3,z+
add r0,r2
adc r1,r3