CFは符号なし実行を示し、OFは符号付きオーバーフローを示すことが知られています。では、アセンブリプログラムはビットのシーケンスにすぎないため、符号なしデータと符号付きデータをどのように区別するのでしょうか。(タイプ情報用の追加のメモリストレージを介して、または位置情報などを介して?)そしてこれらの2つのフラグは交換可能に使用できますか?
6 に答える
違いは、データ自体ではなく、データを操作するために使用される命令にあります。現代のコンピューター (1970 年頃以降) は、2 の補数と呼ばれる整数データの表現を使用します。この表現では、符号付きの数値と符号なしの数値の両方で加算と減算がまったく同じように機能します。
表現の違いは、最上位ビット (符号ビットとも呼ばれます) に与えられる解釈です。符号なしの数値の場合、数値が完全に正の範囲の上半分にある場合、最上位ビットが設定されます。符号付き数値の場合、数値が範囲全体の下半分と負の半分にある場合、最上位ビットが設定されます。
異なる命令は、同じビットの異なる解釈を使用する場合があります。たとえば、ほとんどの大型マシンには、符号付きと符号なしの両方の乗算命令があります。「set less than」命令を使用するマシンには、署名付きと未署名の両方のフレーバーがある場合があります。
OF (オーバーフロー フラグ) は、キャリーが結果の最上位ビットの符号を反転させて、引数の最上位ビットと異なるようにしたかどうかを示します。数値が符号なしと解釈される場合、オーバーフロー フラグは関係ありませんが、符号付きと解釈される場合、OF は、たとえば、2 つの大きな正の数が加算され、結果が負であったことを意味します。
CF (キャリー フラグ) は、ビットがワードから完全に (たとえば、ビット 33 またはビット 65 に) 実行されたかどうかを示します。数値が符号なしとして解釈される場合、キャリー フラグは加算がオーバーフローしたことを意味し、結果が大きすぎて機械語に収まりません。オーバーフロー フラグは関係ありません。
あなたの質問に対する答えは、アセンブリ コードには、署名されたデータと署名されていないデータを区別するいくつかの方法があるということです。
- CF または OF を選択して、符号付きまたは符号なしの比較を行うことができます。
- 符号付きまたは符号なしの乗算および除算命令を選択できます。
- 符号付きまたは符号なしの右シフトを選択できます (符号付きは上位ビットをコピーし、符号なしはゼロでシフトします)。
サインをオペコードしようとしないでください。それは不可能です。代わりに、真実を理解しようとするだけです。兆候はありません。次に、区別するのは記号タイプではなく、自分だけであることがわかります。
署名付きデータと未署名データを処理するためのさまざまなオペコードがあります。プログラムが 2 つの符号付き整数を比較したい場合は、オペコードjl
、jle
、jg
、および を使用しますjge
。ここで、l と g はそれぞれ小さい方と大きい方を表します。プログラムが 2 つの符号なし整数を比較する場合、オペコード、、、および を使用します。ここで、a と b はそれぞれ上と下を表します。e は、すべての場合で「または等しい」を表します。これらのオペコードは、比較に基づく分岐に使用されます。jb
jbe
ja
jae
setCC
同様に、比較に応じてバイトを 0 または 1 に設定する命令もあります。これらは同じように機能します。 setl
、setle
、setg
、setge
、setb
、setbe
、およびその他seta
がsetae
あります。
署名付きオペコードは、フラグ ZF、OF、および SF をテストします。符号なしオペコードは、フラグ ZF、CF、および SF をテストします。テストされた正確な条件については、 JCC命令およびsetCC命令に関する 80386 Programmer's Reference Manual のセクションを参照してください。
そうではありません。フラグは、条件が発生するたびに設定されます。プログラマーは、自分が使用している int の型を知っている必要があり、その情報から、必要に応じてどのフラグを調べるかを知る必要があります。
CPUにバイト/ワード/ロングのタイプをテストして返すように要求する方法はありません。
0xFFは「255」または「-1」を保持する場合があります。これはすべて、プログラムが言うバイトのタイプによって異なります。
「type」、「signess」などの構造は、Javaなどの高級言語にのみ存在し、CPUレベルには存在しません。結局のところ、すべてがCPUにとってバイトであり、これらの値を解釈して操作する方法を整理して知るのはプログラム次第です...
ステータスで見つかったCPUフラグは、テストしてそれに応じて反応するのはコード次第であるパラダイムを強制しません。
Intel CPUでは、MMXレジスタとFPUレジスタは実際には同じレジスタを占有します。したがって、一方の操作の値がもう一方の操作を破棄するため、FPUタイプとMMXタイプの命令を同時に混在させることはできません。通常、いずれかを必要とするプログラムは、FPU命令を発行するなど、1つのモードでアクションを完了してから、MMXを起動する場合がありますが、両方を同時に実行することはできません。
通常、アセンブリ プログラムは、変数が署名されているか署名されていないかを示す特別な情報を変数と一緒に運びません。いつどのフラグをチェックし、いつどの条件を使用するか (つまり、JG の代わりに JA を使用する) を知るのは、プログラマーの仕事です。
したがって、どのコマンドを使用すればよいかがわかるように、使用しようとしている変数のタイプを知る必要があります。これが、ほとんどのプログラミング言語が、プログラマーが符号付き/符号なしの型を交換可能に (つまり、明示的なキャストなしで) 使用すると警告を出す理由です。これは、ハードウェアで行うことができますが、予期しない結果が生じる可能性があるためです。