x86のキャリー/オーバーフローと減算
-
12-11-2019 - |
質問
x86のオーバーフロー&キャリーフラグの周りに頭を包み込もうとしています。
署名された2の補数数を追加するために、フラグは4つの方法のうちの1つでしか生成できません(マイ例は4ビット数字です):
- POS + POS= NEG(オーバーフロー)
- 0111 + 0001= 1000(7 + 1= -8)
- POS + NEG= POS(キャリー)
- 0011 + 1110= 0001(3 + -2= 1)
- 否定+否定=否定(キャリー)
- 1111 + 1111= 1110(-1 + -1= -2)
- NEG + NEG= POS(オーバーフロー&キャリー)
- 1000 + 1001= 0001(-8 + -7= 1)
では、x86アセンブリでは、Aと-b?を追加するものと同じフラグを生成することを求めます。
- 1000 + 1001= 0001(-8 + -7= 1)
解決
これは助けるかもしれない参照表です。これは、x86の追加とサブ指示から生じる可能性がある4つの算術フラグの の可能な組み合わせの例を示しています。'h' '' ud 'と' d 'は、各値の符号なし10進数と符号付き10進表現を表します。たとえば、subの最初の行は0xff - 0xfe= 0x1と表示されます。
しかし、私は短い話はアレックスの答えが正しいことです。
. ADD
A B A + B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d | OF | SF | ZF | CF
---+------+-------+----+------+-------+----+------+-------+----+----+----+---
7F | 127 | 127 | 0 | 0 | 0 | 7F | 127 | 127 | 0 | 0 | 0 | 0
FF | 255 | -1 | 7F | 127 | 127 | 7E | 126 | 126 | 0 | 0 | 0 | 1
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0
FF | 255 | -1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1
FF | 255 | -1 | 0 | 0 | 0 | FF | 255 | -1 | 0 | 1 | 0 | 0
FF | 255 | -1 | FF | 255 | -1 | FE | 254 | -2 | 0 | 1 | 0 | 1
FF | 255 | -1 | 80 | 128 | -128 | 7F | 127 | 127 | 1 | 0 | 0 | 1
80 | 128 | -128 | 80 | 128 | -128 | 0 | 0 | 0 | 1 | 0 | 1 | 1
7F | 127 | 127 | 7F | 127 | 127 | FE | 254 | -2 | 1 | 1 | 0 | 0
SUB
A B A - B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d || OF | SF | ZF | CF
----+------+-------+----+------+-------+----+------+-------++----+----+----+----
FF | 255 | -1 | FE | 254 | -2 | 1 | 1 | 1 || 0 | 0 | 0 | 0
7E | 126 | 126 | FF | 255 | -1 | 7F | 127 | 127 || 0 | 0 | 0 | 1
FF | 255 | -1 | FF | 255 | -1 | 0 | 0 | 0 || 0 | 0 | 1 | 0
FF | 255 | -1 | 7F | 127 | 127 | 80 | 128 | -128 || 0 | 1 | 0 | 0
FE | 254 | -2 | FF | 255 | -1 | FF | 255 | -1 || 0 | 1 | 0 | 1
FE | 254 | -2 | 7F | 127 | 127 | 7F | 127 | 127 || 1 | 0 | 0 | 0
7F | 127 | 127 | FF | 255 | -1 | 80 | 128 | -128 || 1 | 1 | 0 | 1
他のヒント
追加または減算するときにキャリー値とオーバーフロー値のすべての組み合わせが可能です。この回答 の例を見ることができます。
この答え A-B
から取得したキャリーがキャリアの逆数であるという事実を含んでいます。A+(-B)
から取得します。最初のリンクによるコードは、このプロパティを利用してADC
をSBB
に変換します。
符号付きオーバーフローフラグ値は、結果が正しい符号ビットを持ち、両方の場合も符号ビットが同じになるかどうかによって異なりますので、A-B
とA+(-B)
の両方で同じでなければなりません。