デバッガーは、特定の値を保持する複数の擬似レジスタをサポートしています。
デバッガーは 、自動擬似レジスタを特定の 有用な値に設定します。 ユーザー定義の擬似レジスタ は、書き込みまたは読み取り可能な整数変数です。
すべての擬似レジスタはドル記号 ($) で始まります。 MASM 構文を使用している場合は、ドル記号の前にアットマーク ( @ ) を追加できます。 この記号は、次のトークンがシンボルではなくレジスタまたは擬似レジスタであることをデバッガーに通知します。 アット マークを省略すると、デバッガーはシンボル テーブル全体を検索する必要があるため、応答が遅くなります。
たとえば、次の 2 つのコマンドは同じ出力を生成しますが、2 番目のコマンドの方が高速です。
0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f
擬似レジスタと同じ名前のシンボルが存在する場合は、アット マークを追加する必要があります。
C++ 式構文を使用している場合は、アット マーク ( @ ) が常に必要です。
r (Registers) コマンドは、この規則の例外です。 デバッガーは常に最初の引数をレジスタまたは擬似レジスタとして解釈します。 (アットマークは必須または許可されていません。 r コマンドに 2 番目の引数がある場合は、既定の式の構文に従って解釈されます。 既定の式構文が C++ の場合は、次のコマンドを使用して 、$t 2 擬似レジスタを $t 1 擬似レジスタにコピーする必要があります。
0:000> r $t1 = @$t2
自動 Pseudo-Registers
デバッガーは、次の擬似レジスタを自動的に設定します。
擬似レジスタ | 説明 |
---|---|
$ea |
最後に実行された命令の有効なアドレス。 この命令に有効なアドレスがない場合、デバッガーに "無効なレジスタ エラー" と表示されます。 この命令に 2 つの有効なアドレスがある場合、デバッガーは最初のアドレスを表示します。 |
$ea 2 |
実行された最後の命令の 2 番目の有効なアドレス。 この命令に 2 つの有効なアドレスがない場合、デバッガーに "Bad register error" と表示されます。 |
$exp |
評価された最後の式です。 |
$ra |
現在スタック上にあるリターン アドレス。 このアドレスは、実行コマンドで特に便利です。 たとえば、 g @$ra は、リターン アドレスが見つかるまで続行されます ( ただし、gu (Go Up) は、現在の関数の "ステップ アウト" のより正確な方法です)。 |
$ip |
命令ポインター レジスタ。 x86 ベースのプロセッサ:eip と同じです。 Itanium ベースのプロセッサ:iip に関連します。 (詳細については、次の表の注を参照してください)。x64 ベースのプロセッサ:rip と同じです。 |
$eventip |
現在のイベント時の命令ポインター。 通常、このポインターは 、スレッドを切り替えたり、命令ポインターの値を手動で変更したりしない限り、$ipに一致します。 |
$previp |
前のイベントの時点での命令ポインター。 (デバッガーに侵入すると、イベントとしてカウントされます)。 |
$relip |
現在のイベントに関連する命令ポインター。 分岐トレースの場合、このポインターはブランチ ソースへのポインターです。 |
$scopeip |
現在の ローカル コンテキスト ( スコープとも呼ばれます) の命令ポインター。 |
$exentry |
現在のプロセスの最初の実行可能ファイルのエントリ ポイントのアドレス。 |
$retreg |
プライマリ戻り値レジスタ。 x86 ベースのプロセッサ:eax と同じです。 Itanium ベースのプロセッサ:ret0 と同じです。 x64 ベースのプロセッサ:rax と同じです。 |
$retreg 64 |
64 ビット形式のプライマリ戻り値レジスタ。 x86 プロセッサ:edx:eax ペアと同じです。 |
$csp |
現在のコールスタックポインター。 このポインターは、呼び出し履歴の深さを最も代表するレジスタです。 x86 ベースのプロセッサ:esp と同じです。Itanium ベースのプロセッサ:bsp と同じです。 x64 ベースのプロセッサ:rsp と同じです。 |
$p |
最後の d* (Display Memory) コマンドが出力した値。 |
$proc |
現在のプロセスのアドレス (つまり、EPROCESS ブロックのアドレス)。 |
$thread |
現在のスレッドのアドレス。 カーネル モード デバッグでは、このアドレスは ETHREAD ブロックのアドレスです。 ユーザー モード デバッグでは、このアドレスはスレッド環境ブロック (TEB) のアドレスです。 |
$peb |
現在のプロセスのプロセス環境ブロック (PEB) のアドレス。 |
$teb |
現在のスレッドのスレッド環境ブロック (TEB) のアドレス。 |
$tpid |
現在のスレッドを所有するプロセスのプロセス ID (PID)。 |
$tid |
現在のスレッドのスレッド ID。 |
$dtid |
|
$dpid |
|
$dsid |
|
$bp番号 |
対応するブレークポイントのアドレス。 たとえば、 $bp 3 (または $bp 03) は、ブレークポイント ID が 3 のブレークポイントを参照します。 数値 は常に 10 進数です。 ブレークポイントに Number の ID がない場合、 $bpNumber は 0 に評価されます。 ブレークポイントの詳細については、「ブレークポイントの 使用」を参照してください。 |
$frame |
現在のフレーム インデックス。 このインデックスは、 .frame (ローカル コンテキストの設定) コマンドが使用するフレーム番号と同じです。 |
$dbgtime |
デバッガーが実行されているコンピューターに応じた現在の時刻。 |
$callret |
.call (Call Function) が呼び出した、または .fnret /s コマンドで使用される最後の関数の戻り値。 $callretのデータ型は、この戻り値のデータ型です。 |
$extret |
|
$extin |
|
$clrex |
|
$lastclrex |
マネージド デバッグのみ: 最後に検出された共通言語ランタイム (CLR) 例外オブジェクトのアドレス。 |
$ptrsize |
ポインターのサイズ。 カーネル モードでは、このサイズはターゲット コンピューターのポインター サイズです。 |
$pagesize |
1 ページのメモリ内のバイト数。 カーネル モードでは、このサイズはターゲット コンピューターのページ サイズです。 |
$pcr |
|
$pcrb |
|
$argreg |
|
$exr_chance |
現在の例外レコードの確率。 |
$exr_code |
現在の例外レコードの例外コード。 |
$exr_numparams |
現在の例外レコード内のパラメーターの数。 |
$exr_param0 |
現在の例外レコードのパラメーター 0 の値。 |
$exr_param1 |
現在の例外レコードのパラメーター 1 の値。 |
$exr_param2 |
現在の例外レコードのパラメーター 2 の値。 |
$exr_param3 |
現在の例外レコードのパラメーター 3 の値。 |
$exr_param4 |
現在の例外レコードのパラメーター 4 の値。 |
$exr_param5 |
現在の例外レコードのパラメーター 5 の値。 |
$exr_param6 |
現在の例外レコードのパラメーター 6 の値。 |
$exr_param7 |
現在の例外レコードのパラメーター 7 の値。 |
$exr_param8 |
現在の例外レコードのパラメーター 8 の値。 |
$exr_param9 |
現在の例外レコードのパラメーター 9 の値。 |
$exr_param10 |
現在の例外レコードのパラメーター 10 の値。 |
$exr_param11 |
現在の例外レコードのパラメーター 11 の値。 |
$exr_param12 |
現在の例外レコードのパラメーター 12 の値。 |
$exr_param13 |
現在の例外レコードのパラメーター 13 の値。 |
$exr_param14 |
現在の例外レコードのパラメーター 14 の値。 |
$bug_code |
バグ チェックが発生した場合は、これがバグ コードです。 ライブ カーネル モード デバッグとカーネル クラッシュ ダンプに適用されます。 |
$bug_param1 |
バグ チェックが発生した場合、これはパラメーター 1 の値です。 ライブ カーネル モード デバッグとカーネル クラッシュ ダンプに適用されます。 |
$bug_param2 |
バグ チェックが発生した場合、これはパラメーター 2 の値です。 ライブ カーネル モード デバッグとカーネル クラッシュ ダンプに適用されます。 |
$bug_param3 |
バグ チェックが発生した場合、これはパラメーター 3 の値です。 ライブ カーネル モード デバッグとカーネル クラッシュ ダンプに適用されます。 |
$bug_param4 |
バグ チェックが発生した場合、これはパラメーター 4 の値です。 ライブ カーネル モード デバッグとカーネル クラッシュ ダンプに適用されます。 |
これらの擬似レジスタの一部は、特定のデバッグ シナリオでは使用できない場合があります。 たとえば、ユーザー モードのミニダンプまたは特定のカーネル モード ダンプ ファイルをデバッグするときに、$peb、$tid、および$tpidを使用することはできません。 ~ (スレッドの状態) からスレッド情報を学習できるが、$tidからは学習できない状況があります。 最初のデバッガー イベントで $previp 擬似レジスタを使用することはできません。 分岐トレースを行わない限り、 $relip 擬似レジスタを使用することはできません。 使用できない擬似レジスタを使用すると、構文エラーが発生します。
構造体のアドレス ($thread、$proc、$teb、$peb、$lastclrexなど) を保持する擬似レジスタは、C++ 式エバリュエーターの適切なデータ型に従って評価されますが、MASM 式エバリュエーターでは評価されません。 たとえば、コマンド ? $teb は TEB のアドレスを表示し、 コマンド ?? @$teb は TEB 構造全体を表示します。 詳細については、「式の評価」を参照してください。
Itanium ベースのプロセッサでは、 iip レジスタは バンドルアラインされています。つまり、別のスロットが実行されている場合でも、現在の命令を含むバンドル内のスロット 0 を指します。 したがって、 iip は完全な命令ポインターではありません。 $ip擬似レジスタは、バンドルとスロットを含む実際の命令ポインターです。 アドレス ポインター ($ra、$retreg、$eventip、$previp、$relip、$exentry) を保持する他の擬似レジスタは、すべてのプロセッサで$ipと同じ構造を持ちます。
r コマンドを使用して、$ipの値を変更できます。 この変更により、対応するレジスタも自動的に変更されます。 実行が再開されると、新しい命令ポインター アドレスで再開されます。 このレジスタは、手動で変更できる唯一の自動擬似レジスタです。
手記MASM 構文では、ピリオド ( . ) で$ip擬似レジスタを指定できます。 この期間の前にアットマーク (@) を追加せず、 r コマンドの最初のパラメーターとしてピリオドを使用しないでください。 この構文は、C++ 式内では使用できません。
自動擬似レジスタは、 自動エイリアスに似ています。 ただし、エイリアス関連のトークン ( ${ }など) と共に自動エイリアスを使用できます。このようなトークンで擬似レジスタを使用することはできません。
User-Defined Pseudo-Registers
ユーザー定義の擬似レジスタは 20 個あります ($t 0、 $t 1、...、 $t 19)。 これらの擬似レジスタは、デバッガーを通じて読み書きできる変数です。 これらの擬似レジスタには任意の整数値を格納できます。 これらは、ループ変数として特に便利です。
次の例に示すように、これらの擬似レジスタのいずれかに書き込むには、 r (Registers) コマンドを使用します。
0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)
すべての擬似レジスタと同様に、次の例に示すように、任意の式でユーザー定義の擬似レジスタを使用できます。
0:000> bp $t3
0:000> bp @$t4
0:000> ?? @$t1 + 4*@$t2
擬似レジスタは、? スイッチを rコマンド と共に使用しない限り、常に整数型として指定されます。 このスイッチを使用すると、擬似レジスタは割り当てられているものの型を取得します。 たとえば、次のコマンドは、UNICODE_STRING** 型と0x0012FFBC値を $t 15 に割り当てます。
0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc
ユーザー定義の擬似レジスタは、デバッガーの起動時に既定値として 0 を使用します。
手記 エイリアス $u 0、 $u 1、...、 $u 9 は、外観が似ているにもかかわらず擬似レジスタではありません。 これらのエイリアスの詳細については、「エイリアスの 使用」を参照してください。
の例
次の例では、現在のスレッドが NtOpenFile を呼び出すたびにヒットするブレークポイントを設定します。 ただし、他のスレッドが NtOpenFile を呼び出しても、このブレークポイントはヒットしません。
kd> bp /t @$thread nt!ntopenfile
の例
次の例では、レジスタが指定した値を保持するまでコマンドを実行します。 まず、条件付きステップ実行用の次のコードを "eaxstep" という名前のスクリプト ファイルに配置します。
.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }
次に、次のコマンドを発行します。
t "$<eaxstep"
デバッガーはステップを実行し、コマンドを実行します。 この場合、デバッガーはスクリプトを実行します。スクリプトには 1234 が表示されるか、プロセスが繰り返されます。