鉛筆と紙で小学校に戻ります。1234と5678を追加したい場合
1234
+ 5678
======
4+8は2キャリー1
1
1234
+ 5678
======
2
等々
00110 <-- carry bits
1234 <-- first operand
+ 5678 <-- second operand
======
6912
1列の上のキャリービットは重要であり、キャリーインと呼ばれ、左端の列を離れるキャリービットが実行されます。
一度に2列追加するのに十分な幅の用紙しかない場合はどうなりますか?
110
34
+ 78
======
12
下の2桁のセットから始め、キャリーインとしてゼロが必要です。キャリーアウトで結果12が得られます。
今、私はその実行を取り、次の2桁の持ち込みとして使用します。この加算器は、前の加算からキャリーを取得して、この加算のキャリーインとして使用できる必要があります。
001
12
+ 56
====
69
すべてを言い終えると、69と12が得られます。これらを組み合わせると、6912が得られますが、そこに到達するために4桁の全加算器は必要ありませんでした。これを永久に繰り返すことも、メモリ、レジスタ、またはクロックサイクルがなくなるまで繰り返すこともできます。
avrには問題を解決する他の方法があるかもしれませんが、ほとんどのプロセッサーには少なくとも2つの形式の加算と2つの形式の減算があるため、加算器を必要な幅にカスケードできます。avrの命令セットを調べてください。上で起こっていることがあなたに飛び出すはずです。
編集:
ACの例が役立つかもしれません...(16進数への切り替え)
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);
EDIT2:
これが宿題ではないことを願っています...
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ポインタレジスタの1つを使用します
;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