疑似レジスタの構文
デバッガーは、特定の値を保持する複数の擬似レジスタをサポートしています。
デバッガーは、自動擬似レジスタを特定の有用な値に設定します。 ユーザー定義の擬似レジスタは、書き込みまたは読み取り可能な整数変数です。
すべての擬似レジスタはドル記号 ($) で始まります。 MASM 構文を使用している場合、ドル記号の前にアット マーク (@) を追加できます。 このアット マークは、次のトークンがシンボルではなくレジスタまたは擬似レジスタであることをデバッガーに通知します。 アット マークを省略した場合、デバッガーはシンボル テーブル全体を検索する必要があるため、応答が遅くなります。
たとえば、次の 2 つのコマンドは同じ出力を生成しますが、2 番目のコマンドの方が高速です。
0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f
擬似レジスタと同じ名前のシンボルが存在する場合、アット マークを追加する必要があります。
C++ 式構文を使用している場合は、アット マーク (@) が常に必要です。
r (レジスタ) コマンドは、この規則の例外です。 デバッガーは、常に最初の引数をレジスタまたは擬似レジスタとして解釈します。 (アットマークは必須ではなく、許可もされません)。r コマンドに 2 番目の引数がある場合、それは既定の式構文に従って解釈されます。 既定の式構文が C++ の場合は、次のコマンドを使用して $t2 擬似レジスタを $t1 擬似レジスタにコピーする必要があります。
0:000> r $t1 = @$t2
自動擬似レジスタ
デバッガーは、次の擬似レジスタを自動的に設定します。
擬似レジスタ | 説明 |
---|---|
$ea |
直近に実行された命令の有効なアドレス。 この命令に有効なアドレスがない場合、デバッガーに "無効なレジスタ エラー" と表示されます。 この命令に 2 つの有効なアドレスがある場合、デバッガーは最初のアドレスを表示します。 |
$ea2 |
直近に実行された命令の 2 番目の有効なアドレス。 この命令に 2 つの有効なアドレスがない場合、デバッガーに "無効なレジスタ エラー" と表示されます。 |
$exp |
評価された直近の式。 |
$ra |
現在スタック上にある返信先アドレス。 このアドレスは、実行コマンドで特に役立ちます。 たとえば、g $@ra は、返信先アドレスが見つかるまで続行されます (ただし、gu (完了まで実行) は、現在の関数の "ステップ アウト" のより正確な方法です)。 |
$ip |
命令ポインター レジスタ。 x86 ベースのプロセッサ:eip と同じです。 Itanium ベースのプロセッサ:iip に関連しています。 (詳しくは、次の表の注をご覧ください)。x64 ベースのプロセッサ:rip と同じです。 |
$eventip |
現在のイベント時の命令ポインター。 通常、このポインターは、スレッドを切り替えたり、命令ポインターの値を手動で変更したりしない限り、$ip と一致します。 |
$previp |
前のイベント時の命令ポインター。 (デバッガーに分割すると、イベントとしてカウントされます)。 |
$relip |
現在のイベントに関連している命令ポインター。 ブランチ トレースの場合、このポインターはブランチ ソースへのポインターです。 |
$scopeip |
現在のローカル コンテキスト (スコープとも呼ばれます) の命令ポインター。 |
$exentry |
現在のプロセスの最初の実行可能ファイルのエントリ ポイントのアドレス。 |
$retreg |
プライマリ戻り値レジスタ。 x86 ベースのプロセッサ:eax と同じです。 Itanium ベースのプロセッサ:ret0 と同じです。 x64 ベースのプロセッサ:rax と同じです。 |
$retreg64 |
64 ビット形式のプライマリ戻り値レジスタ。 x86 プロセッサ:edx:eax ペアと同じです。 |
$csp |
現在の呼び出しスタック ポインター。 このポインターは、呼び出しスタックの深さを最も表すレジスタです。 x86 ベースのプロセッサ:esp と同じです。Itanium ベースのプロセッサ:bsp と同じです。 x64 ベースのプロセッサ:rsp と同じです。 |
$p |
直近の d* (表示メモリ) コマンドが出力した値。 |
$proc |
現在のプロセスのアドレス (つまり、EPROCESS ブロックのアドレス)。 |
$thread |
現在のスレッドのアドレス。 カーネル モード デバッグでは、このアドレスは ETHREAD ブロックのアドレスです。 ユーザー モード デバッグでは、このアドレスはスレッド環境ブロック (TEB) のアドレスです。 |
$peb |
現在のプロセスのプロセス環境ブロック (PEB) のアドレス。 |
$teb |
現在のスレッドのスレッド環境ブロック (TEB) のアドレス。 |
$tpid |
現在のスレッドを所有するプロセスのプロセス ID (PID)。 |
$tid |
現在のスレッドのスレッド ID。 |
$dtid |
|
$dpid |
|
$dsid |
|
$bpNumber |
対応するブレークポイントのアドレス。 たとえば、$bp3 (または $bp03) は、ブレークポイント ID が 3 のブレークポイントを参照します。 Number は常に 10 進数です。 ブレークポイントに Number の ID がない場合、$bpNumber は 0 に評価されます。 ブレークポイントの詳細については、「ブレークポイントの使用」を参照してください。 |
$frame |
現在のフレーム インデックス。 このインデックスは、.frame (ローカル コンテキストの設定) コマンドが使用するフレーム番号と同じです。 |
$dbgtime |
デバッガーが実行されているコンピューターに応じた現在の時刻。 |
$callret |
.call (呼び出し関数) が呼び出した、または .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++ 式内では使用できません。
自動擬似レジスタは、自動エイリアスに似ています。 ただし、エイリアス関連のトークン (${ } など) と共に自動エイリアスを使用できます。このようなトークンで擬似レジスタを使用することはできません。
ユーザー定義擬似レジスタ
ユーザー定義の擬似レジスタは 20 個あります ($t0、$t1、...、$t19)。 これらの擬似レジスタは、デバッガーを通じて読み書きできる変数です。 これらの擬似レジスタには、任意の整数値を格納できます。 これらは、ループ変数として特に役立ちます。
次の例に示すように、これらの擬似レジスタのいずれかに書き込むには、r (レジスタ) コマンドを使用します。
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 値を $t15 に割り当てます。
0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc
ユーザー定義の擬似レジスタは、デバッガーの起動時に既定値として 0 を使用します。
注 エイリアス $u0、$u1、...、$u9 は、外観が似ているにもかかわらず擬似レジスタではありません。 これらのエイリアスの詳細については、「エイリアスの使用」を参照してください。
例
次の例では、現在のスレッドが NtOpenFile を呼び出すたびにヒットするブレークポイントを設定します。 ただし、他のスレッドが NtOpenFile を呼び出しても、このブレークポイントはヒットしません。
kd> bp /t @$thread nt!ntopenfile
例
次の例では、レジスタが指定した値を保持するまでコマンドを実行します。 まず、条件付きステップ実行用の次のコードを "eaxstep" という名前のスクリプト ファイルに配置します。
.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }
次に、以下のコマンドを実行します。
t "$<eaxstep"
デバッガーはステップを実行し、コマンドを実行します。 この場合、デバッガーはスクリプトを実行します。1234 と表示されるか、プロセスが繰り返されます。