Addとadduの違いについて混乱しています。
MIPS命令リファレンスは次のように述べています。
私の理解は、符号付きオペランドでaddを使用し、符号なしオペランドでadduを使用することです。
しかし、この例を考えてみましょう(6ビットのみ):
オーバーフロー | V 1 | 1 1 1 <-キャリー | 1 1 1 1 0 1 + | 1 1 1 1 1 0 = ----------------- | 1 1 1 0 1 1
そしてこれは私の推論です:
今私の質問は:
命令名は誤解を招くものです。 notオーバーフローでトラップが必要な場合は、符号付きオペランドと符号なしオペランドの両方にaddu
を使用します。
何らかの理由でオーバーフローのトラップが必要な場合は、add
を使用してください。ほとんどの言語は、署名されたオーバーフローのトラップを望まないため、add
が役立つことはほとんどありません。
符号付きの数値を使用している場合、結果がオーバーフローしたときにトラップを生成するには、add
を使用する必要があります。
符号なしの数値を使用している場合は、常にaddu
を使用し、結果をいずれかの数値と比較して加算のオーバーフローを確認する必要があります(結果がオペランドよりも小さい場合、加算はオーバーフローしました)。
署名なしの追加でオーバーフローをチェックする方法を示すスニペットを次に示します。
li $a1, 0xFFFF0FFF
li $a2, 0x00010000
addu $a3, $a1, $a2 # This unsigned addition overflows (set $a3 to $a1+$a2)
bgt $a1, $a3, overflowed
bgt $a1, $a2, overflowed
# If you get here, unsigned addition did not overflow
# your code goes here...
overflowed:
# If you get here, unsigned addition overflowed
# your code goes here...
OVERFLOW is [〜#〜] not [〜#〜]質問で宣言されているように、このキャリービットはオーバーフロービットではありません。この例では、OVERFLOWはなく、オーバーフローは次の場合に発生します。
MSB1 = 1 && MSB2 = 1 && MSBofRESULT = 0
OR
MSB1 = 0 && MSB2 = 0 && MSBofRESULT = 1
したがって、add
に固執すると、オーバーフローのフラグが立てられ、例のキャリービット(オーバーフローではない)が気になりません。 addu
は、例外が発生しないことを除いて、同じことを行います。
基本的に両方のオペコードは符号付き加算です。 MIPSでは31ビットを使用してデータを格納し、最大数は(2を31に上げる)-1で、1ビットは数値の符号を格納するために予約されています。上記で説明したように、「add」と「addu」の基本的な違いは、結果の数が31ビットが占有する最大数より大きい場合に前者が例外をスローすることです。後者は警告を表示せずに実行されます。
たとえば、3ビットの加算の最大値num =(2 **(n-1))-1 minumem num =-(2 **(n-1))したがって、この場合、max = 3およびmin = -4
li $t1,3
li $t2,1
add $t3,$t1,$t2 -----> throws an arthimetic overflow exception
addu $t3,$t1,$t2 ------> t3 = -4
それだ。
あなたの例では実際にはオーバーフローではありません。オーバーフローは、符号ビットへのキャリーが符号ビットのキャリーと等しくないときに発生します。あなたの例では、符号ビットの桁上げは "1"(オーバーフローのように見える)ですが、符号ビットへの桁上げも "1"です。したがって、この状態ではMIPSはそれをオーバーフローと見なしません。オーバーフローが発生するパターンは、実際には結果が正しいかどうかに対応しています。つまり、結果がビットが表現できる範囲外の場合、オーバーフローが発生します。たとえば、2つの4ビット数値0111(7)と0010(2)を一緒に追加すると、結果(9)が4ビット数値が表すことができる範囲(-8〜7)を超えているため、オーバーフローが発生します。 。あなたが算術を見れば:
0111 (7) + 0010 (2) = 1001 (-7)
符号ビットのキャリーはありませんが、結果はまだ正しくないことがわかります。したがって、これはオーバーフローです(そしてMIPSがそれを検出します)。