署名拡張機能
32 ビットの符号付き整数が負の場合、その最上位ビットは 1 に等しくなります。 この 32 ビットの符号付き整数を 64 ビットの数値にキャストする場合、上位ビットを 0 に設定する (符号なし整数と数値の 16 進値を保持する) か、上位ビットを 1 に設定する (数値の符号付き値を保持する) ことができます。 後者の状況は符号拡張と呼ばれます。
デバッガーは、MASM 式、C++ 式、および数値を表示する際の符号拡張に関するさまざまなルールに従います。
MASM 式の符号拡張
特定の条件下では、数値は MASM 式エバリュエーターによって自動的に符号拡張されます。 符号拡張は、0x80000000 から 0xFFFFFFFF までの数値にのみ影響します。 つまり、符号拡張は、上位ビットが 1 である 32 ビットで書き込むことができる数値にのみ影響を与えます。
数値 0x12345678 は、デバッガーが 64 ビット数値として扱う場合、常に 0x00000000`12345678 のままです。 一方、0x890ABCDE が 64 ビット値として扱われる場合、0x00000000`890ABCDE のままになるか、MASM 式エバリュエーターが 0xFFFFFFFF`890ABCDE に符号拡張する可能性があります。
0x80000000 から 0xFFFFFFFF までの数値は、次の基準に基づいて符号拡張されます。
ユーザー モードでは数値定数が符号拡張されることはありません。 カーネル モードでは、下位バイトの前に抑音アクセント (`) が含まれていない限り、数値定数は符号拡張されます。 たとえば、カーネル モードでは、16 進数 EEAA1122 と 00000000EEAA1122 は符号拡張されますが、00000000`EEAA1122 と 0`EEAA1122 は符号拡張されません。
32 ビット レジスタはどちらのモードでも符号拡張されます。
疑似レジスタは常に 64 ビット値として格納されます。 これらは評価時に符号拡張されません。 擬似レジスタに値が割り当てられると、使用される式は標準の C++ 基準に従って評価されます。
式内の個々の数値とレジスタは符号拡張できますが、式の評価中の他の計算は符号拡張されません。 その結果、次の構文を使用して数値またはレジスタの上位ビットをマスクできます。
( 0x0`FFFFFFFF & expression )
C++ 式の符号拡張
デバッガーが C++ 式を評価する場合、次のルールが適用されます。
レジスタと疑似レジスタは符号拡張されません。
他のすべての値は、C++ がその型の値を扱うのとまったく同じように扱われます。
符号拡張された 64 ビット数値の表示
32 ビットおよび 16 ビットのレジスタを除くすべての数値は、デバッガ内で 64 ビット値として内部的に保存されます。 ただし、数値が特定の基準を満たす場合、デバッガーはコマンド出力にその数値を 32 ビット数値として表示します。
デバッガーは、次の基準を使用して数値の表示方法を決定します。
数値の上位 32 ビットがすべて 0 の場合 (つまり、数値が 0x00000000`00000000 ~ 0x00000000`FFFFFFFF の場合)、デバッガーは数値を 32 ビット数値として表示します。
数値の上位 32 ビットがすべて 1 で、下位 32 ビットの最上位ビットも 1 の場合 (つまり、数値が 0xFFFFFFFF`80000000 ~ 0xFFFFFFFF`FFFFFFFF の場合)、デバッガーは、数値が符号拡張された 32 ビット数値であると想定し、32 ビット数値として表示します。
前の 2 つの条件が当てはまらない場合 (つまり、数値が 0x00000001`00000000 ~ 0xFFFFFFFF`7FFFFFFF の場合)、デバッガーは数値を 64 ビット数値として表示します。
このような表示規則のため、数値を 0x80000000 ~ 0xFFFFFFFF の 32 ビット数値で表示した場合、上位 32 ビットがすべて 1 であるか、すべて 0 であるかを確認することはできません。 これら 2 つのケースを区別するには、数値に対して追加の計算 (1 つ以上の上位ビットをマスクして結果を表示するなど) を実行する必要があります。