Share via


Pseudo-Register 語法

偵錯工具支援數個保存特定值的虛擬暫存器。

偵錯工具會將 自動虛擬暫存器 設定為特定的實用值。 使用者定義的虛擬暫存器 是您可以寫入或讀取的整數變數。

所有虛擬暫存器都是以貨幣符號開頭, ($) 。 如果您使用 MASM 語法,您可以在貨幣符號之前新增 at sign ( @ ) 。 這在符號上會告訴偵錯工具下列權杖是暫存器或虛擬暫存器,而不是符號。 如果您省略 at 符號,偵錯工具回應的速度會比較慢,因為它必須搜尋整個符號表。

例如,下列兩個命令會產生相同的輸出,但第二個命令的速度較快。

0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f

如果符號與虛擬暫存器的名稱相同,您必須新增 at 符號。

如果您使用 C++ 運算式語法,則一律需要正負號 ( @ ) 。

r (Registers) 命令是此規則的例外狀況。 偵錯工具一律會將第一個引數解譯為暫存器或虛擬暫存器。 (不需要或允許 at 符號。) 如果 r 命令有第二個引數,則會根據預設運算式語法加以解譯。 如果預設運算式語法為 C++,您必須使用下列命令,將 $t 2 虛擬暫存器複製到 $t 1 虛擬暫存器。

0:000> r $t1 = @$t2

自動 Pseudo-Registers

偵錯工具會自動設定下列虛擬暫存器。

虛擬暫存器 Description

$ea

執行的最後一個指令的有效位址。 如果此指令沒有有效的位址,偵錯工具會顯示「註冊錯誤」。 如果此指令有兩個有效的位址,偵錯工具會顯示第一個位址。

$ea 2

執行的最後一個指令的第二個有效位址。 如果此指令沒有兩個有效位址,偵錯工具會顯示「註冊錯誤錯誤」。

$exp

評估的最後一個運算式。

$ra

目前位於堆疊上的傳回位址。

此位址在執行命令中特別有用。 例如, g @$ra 會繼續直到找到傳回位址 (雖然 gu (Go Up) 是更精確的目前函式) 「逐步執行」的有效方式。

$ip

指令指標暫存器。

x86 處理器:eip相同。 以 Itanium 為基礎的處理器:iip相關。 (如需詳細資訊,請參閱下表後面的附注.) x64 型處理器:擷取相同。

$eventip

目前事件時的指令指標。 除非您切換執行緒或手動變更指令指標的值,否則此指標通常會符合 $ip

$previp

上一個事件時的指令指標。 (中斷至偵錯工具會計算為 event.)

$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* (顯示記憶體) 命令列印的值。

$proc

目前進程 (的位址,也就是 EPROCESS 區塊的位址) 。

$thread

目前線程的位址。 在核心模式偵錯中,此位址是 ETHREAD 區塊的位址。 在使用者模式偵錯中,此位址是執行緒環境區塊的位址, (TEB) 。

$peb

進程環境區塊的位址 (目前進程的 PEB) 。

$teb

執行緒環境區塊的位址 (目前線程的 TEB) 。

$tpid

擁有目前線程之進程的進程識別碼 (PID) 。

$tid

目前線程的執行緒識別碼。

$dtid

$DPId

$dsid

$bp編號

對應中斷點的位址。 例如, $bp 3 (或 $bp 03) 是指中斷點識別碼為 3 的中斷點。 數位 一律是十進位數。 如果沒有中斷點的識別碼為 Number$bpNumber 會評估為零。 如需中斷點的詳細資訊,請參閱 使用中斷點

$frame

目前的框架索引。 這個索引與 .frame (設定本機內容) 命令所使用的畫面編號相同。

$dbgtime

根據偵錯工具執行所在的電腦,目前的時間。

$callret

.call (呼叫函式) 呼叫或用於.fnret /s命令的最後一個函式傳回值。 $callret的資料類型是這個傳回值的資料類型。

$extret

$extin

$clrex

$lastclrex

僅限 Managed 偵錯: 上次遇到的 Common Language Runtime 位址 (CLR) 例外狀況物件。

$ptrsize

指標的大小。 在核心模式中,此大小是目的電腦上的指標大小。

$pagesize

一頁記憶體中的位元組數目。 在核心模式中,此大小是目的電腦上的頁面大小。

$pcr

$pcrb

$argreg

$exr_chance

目前例外狀況記錄的機會。

$exr_code

目前例外狀況記錄的例外狀況程式碼。

$exr_numparams

目前例外狀況記錄中的參數數目。

$exr_param0

目前例外狀況記錄中的 Parameter 0 值。

$exr_param1

目前例外狀況記錄中的 Parameter 1 值。

$exr_param2

目前例外狀況記錄中的 Parameter 2 值。

$exr_param3

目前例外狀況記錄中的 Parameter 3 值。

$exr_param4

目前例外狀況記錄中的 Parameter 4 值。

$exr_param5

目前例外狀況記錄中的 Parameter 5 值。

$exr_param6

目前例外狀況記錄中的 Parameter 6 值。

$exr_param7

目前例外狀況記錄中的 Parameter 7 值。

$exr_param8

目前例外狀況記錄中的 Parameter 8 值。

$exr_param9

目前例外狀況記錄中的 Parameter 9 值。

$exr_param10

目前例外狀況記錄中的 Parameter 10 值。

$exr_param11

目前例外狀況記錄中的 Parameter 11 值。

$exr_param12

目前例外狀況記錄中的 Parameter 12 值。

$exr_param13

目前例外狀況記錄中的 Parameter 13 值。

$exr_param14

目前例外狀況記錄中的 Parameter 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虛擬暫存器。) 。 您在此句點之前不會新增 at sign (@) ,也不會使用句點做為 r 命令的第一個參數。 C++ 運算式中不允許此語法。

自動虛擬暫存器類似于 自動別名。 但是,您可以將自動別名與別名相關的權杖一起使用, (例如 ${ }) ,而且您無法搭配這類權杖使用虛擬暫存器。

使用者定義 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

使用者定義虛擬暫存器會在偵錯工具啟動時使用零作為預設值。

注意 $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 或重複此程式。