-1は、4ビットのバイナリで(2の補数)1111として表すことができます。
15は1111としても表されます。
では、CPUはメモリから値を取得するときに、15と-1をどのように区別しますか?
CPUは、バイトをある場所から別の場所に移動するときに、バイトが-1または15のどちらを保持するかを気にしません。 「署名された移動」のようなものはありません(同じサイズの場所へ-より大きなまたはより小さな目的地のための署名された移動があります)。
CPUは、バイトに対して算術演算を行う場合にのみ、表現を考慮します。 CPUは、ユーザー(またはユーザーに代わってコンパイラー)が選択したオペコードに従って、符号付き演算と符号なし演算のどちらを実行するかを認識しています。
以前の回答のほとんどは、個別のオペコードについて言及していました。これは、乗算や除算などのより複雑な演算には当てはまるかもしれませんが、CPUの動作とは異なる単純な加算と減算には当てはまります。
CPUは、命令の結果に関するデータをフラグレジスタに保持します。 x86(私が最もよく知っている場所)では、ここで最も重要な2つのフラグは、「オーバーフロー」フラグと「キャリー」フラグです。
基本的に、CPUは、番号が符号付きか符号なしかを気にせず、両方を同じように扱います。キャリーフラグは、数値が含まれる可能性のある最大の符号なし値を超えると設定されます。オーバーフローフラグは、符号なし数値の範囲を超えたり下回ったりすると設定されます。符号なしの数値を使用している場合は、キャリーフラグを確認し、オーバーフローフラグを無視します。符号付き数値を使用している場合は、オーバーフローフラグを確認し、キャリーフラグを無視します。
ここではいくつかの例を示します。
署名なし:
1111(15)+ 1111(15)= 1110(14)
あなたが今していることは、キャリーフラグをチェックすることです。この場合、キャリーフラグには最終結果を与えるものが含まれています。
1 1110(30)
署名:
1111(-1)+ 1111(-1)= 1110(-2)
この場合、キャリーフラグを無視すると、オーバーフローフラグはゼロに設定する必要があります。
署名なし:
0111(7)+ 0111(7)= 1110(14)
キャリーフラグをチェックすると、ゼロになります。
署名:
0111(7)+ 0111(7)= 1110(-2)
この場合、オーバーフローフラグが設定され、加算にエラーがあったことを意味します。
したがって、要約すると、数値は、その解釈に基づいて符号付きまたは符号なしのみであり、CPUは、それらを区別するために必要なツールを提供しますが、それ自体では区別しません。
CPUは、数値が符号付きか符号なしかを認識しません。コンパイラは、機械語ファイルを作成するときに、実行する正しい演算を選択して、その番号で数学演算を実行します。たとえば、変数を符号付きタイプとして宣言した場合、機械語で実行される操作は、そのメモリ位置を符号付きの値として扱う操作になります。
どんな種類のソフトウェアでも、データを解釈するときに意味を与えるのは常にです。メモリ内のバイトは、符号付きまたは符号なしの数値、文字、音楽ファイルの一部、画像のピクセルなどです。意味を与えるのは、そのバイトの使用方法です。
コンパイラレベルでは、区別はデータ型に基づいています。データ型がintの場合、4バイトがその変数に割り当てられます(C)。したがって、2の補数の15は00000000 00000000 00000000 00000000 00001111
であり、-1は11111111 11111111 11111111 11111111
です。次に、コンパイラはこれをCPUの対応するオペコードに変換します。 CPUはこのオペコードを実行し、このレベルではすべてが1と0の形式になります。
アクセス可能な最小単位は1バイトです。それは8ビットです。 8ビット表現では、15は00001111として格納されます。コンパイラは、符号ビットから正の数と負の数を区別します。 MSBは符号ビットです。 0の場合は正の数を意味します。 1の場合、負の数を意味します。 15の2進表現のMSBは0です。これは正の数を意味し、00001111は+15に対応します。 -1の8ビットバイナリは11111111であり、MSBが1であるため、負の数になります。コンパイラは最初に2の補数を取り、次に負の符号で数値を表示します。数値を格納するために8ビットがある場合、格納できる最大値は(2 ^ 7)-1であり、その表現には7ビットが必要です。これは、正の数の場合、MSBが常にゼロであることを意味します。あなたの質問のように、数値を格納するために4ビットを取ると仮定すると、最後のビットは符号を保持するための予約であるため、値を格納するために3ビットを使用できます。 3ビットまで、格納できる最大値は(2 ^ 3)-1 = 7です。これは、15を4ビットに格納できないことを意味します。したがって、1111はコンパイラによって常に-1と見なされます。
以下のリンクをたどって、このような難しい質問があるYouTubeチャンネルにアクセスしてください。 www.YouTube。 com/watch?v = ZxRHOT3pzx4
15を表す2の補数では、5ビットが必要です。2の補数の範囲は-16〜15なので、値は01111になります。ここで、MSBビットは0なので、-1の正の値は11111になります。