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

その背後にある「数学」について:それは10進法とまったく同じです:

1 桁の数字を 2 つ足す場合、2 つのケースを考慮する必要があります。2 つの合計が新しい 1 桁の数字 (5+4 = 9) になるか、「オーバーフロー」が発生して別の数字が必要になります (5+6 = 11)。任意の 2 つの数値 (基数は 10、2、256 など) のn桁長の場合、2 つの合計は常に最小桁数の 2 倍よりも小さくなることに注意してくださいn+1。letijbe は、たとえば長さ 1 の数値 (基数 10) です。つまり、両方とも と の間0にあり9ます。10length の最小数と同様n+1 = 2に、それらの合計は常に より小さくなり2 x 10ます。

2 つの数値を加算する場合、オーバーフローが発生しない場合と、ちょうど 1 のオーバーフローが発生する場合があります。キャリー ビットには、最後の算術演算からのこのオーバーフローが格納されます。0か1です。

したがって、それぞれ 4x 8 ビットの 2 つの数値 (4 桁の 256 基数と見なすことができます) を加算する場合、最初の加算で考慮されるオーバーフローはありませんADDADDに対する操作と見なすことができますx = x + y + 0。ただし、最初の追加の後、考慮に入れる必要があるオーバーフローが発生する可能性がありますADDCADDCは の操作を表します。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 オペコードを使用して定数を追加できることを忘れないでください。たとえば、R18:R19 に 5 を追加するには:

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 に答える