Motorola68000およびIntelx86アーキテクチャは、左シフトからのオーバーフローを異なる方法で処理すると聞きました。具体的には、68kLSLとIntelSAL/SHLの組み立て手順です。
誰かがこれの詳細を知っていますか?彼らは異なるフラグを設定しますか、それとも異なる方法で設定しますか?これをリファレンスマニュアルで調べてみましたが、違いはわかりません。なぜこの状況を別の方法で処理したいのでしょうか。
Xビットは関係しません。68000フラグに関する混乱は、2つの左シフト命令があるために発生します。
x86命令セットはそれほど強力ではありません。シフトカウント=1の場合、OF、オーバーフローフラグ=(MSB XOR CF)、つまり、MSBが1ビットシフトの結果として符号を変更した場合、OF = 1、それ以外の場合はOF=0。
シフトカウントが1より大きい場合、OFは未定義です。 (SHLに関するIntelのドキュメントのHTML抽出)。
CPU のプログラマーズ マニュアルには、詳細が記載されています。
X — Set according to the last bit shifted out of the operand;
unaffected for a shift count of zero.
N — Set if the result is negative; cleared otherwise.
Z — Set if the result is zero; cleared otherwise.
V — Always cleared.
C — Set according to the last bit shifted out of the operand;
cleared for a shift count of zero.
インテル x86 :
そのため、オーバーフロー フラグの扱いが異なります。x86 では、2 の乗算 (1 ビット左シフト) でオーバーフローが発生した場合に通知されます。1ビットシフトだけに限定されている理由がわかりません。OFフラグが「最後の」ビットシフトに従って設定されると推測します(これは単なる推測です)。これは、操作全体がオーバーフローしたかどうかを示していない可能性があるため、Intelはそれを「未定義」として文書化しました。
(はい、1979 年のモトローラ 68000 リファレンスを見直しています。)
おそらくあなたが考えているのは、68000 のかなり奇妙な X ビットです。eXtend ビットは、本質的に C (キャリー) ビットのコピーですが、非算術命令の影響を受けません。たとえば、12 ワードの整数を追加するとします。x86 では、次のように表示される場合があります。
.
.
loop:
ADC AX,[SI] ; recycle carry-out from last iter as carry-in to this one
LEA SI, [SI+2] ; flags untouched
INC BX ; BX is loop index. sets all flags except CF
CMP BX, 12 ; doh, changes carry (BUG)
JB loop
このコードは、比較命令がキャリー フラグを台無しにするため機能しません。loop
これが、フラグを変更せずに CX をゼロまでカウントダウンする命令が歴史的に有用であった理由の 1 つです。dec
/を使用してゼロまでカウントダウンすることjnz
もできますが、最新の x86 では部分的なフラグの停止が発生します。残念ながらloop
現在も遅いので、486 あたりから Sandybridge まで、このようなループを作る良い方法がありませんでした。
しかし、68000 では:
.
.
loop:
ADDX.W (A0)+, D0 ; both C and X set the same
INC.W D7 ; D7 is loop index
CMP.W #12, D7 ; harms C, but X left intact
BCC loop
Motorola は、プログラマーに有利に働いていると考えていましたが、X ビット ビジネスは、その価値以上の混乱を引き起こしました。