Sintaks Pseudo-Register

Debugger mendukung beberapa pseudo-register yang menyimpan nilai tertentu.

Debugger mengatur pseudo-register otomatis ke nilai tertentu yang berguna. Pseudo-register yang ditentukan pengguna adalah variabel bilangan bulat yang dapat Anda tulis atau baca.

Semua pseudo-register dimulai dengan tanda dolar ($). Jika Anda menggunakan sintaks MASM, Anda dapat menambahkan tanda ( @ ) sebelum tanda dolar. Tanda ini memberi tahu debugger bahwa token berikut adalah register atau pseudo-register, bukan simbol. Jika Anda menghilangkan tanda saat ini, debugger merespons lebih lambat, karena harus mencari seluruh tabel simbol.

Misalnya, dua perintah berikut menghasilkan output yang sama, tetapi perintah kedua lebih cepat.

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

Jika simbol ada dengan nama yang sama dengan pseudo-register, Anda harus menambahkan tanda at.

Jika Anda menggunakan sintaks ekspresi C++, tanda @ ( ) selalu diperlukan.

Perintah r (Registers) adalah pengecualian untuk aturan ini. Debugger selalu menafsirkan argumen pertamanya sebagai register atau pseudo-register. (Tanda tidak diperlukan atau diizinkan.) Jika ada argumen kedua untuk perintah r , argumen tersebut ditafsirkan sesuai dengan sintaks ekspresi default. Jika sintaks ekspresi default adalah C++, Anda harus menggunakan perintah berikut untuk menyalin pseudo-register $t 2 ke pseudo-register $t 1 .

0:000> r $t1 = @$t2

Pseudo-Registers otomatis

Debugger secara otomatis mengatur pseudo-register berikut.

Pseudo-register Deskripsi

$ea

Alamat efektif dari instruksi terakhir yang dijalankan. Jika instruksi ini tidak memiliki alamat yang efektif, debugger menampilkan "Kesalahan pendaftaran buruk". Jika instruksi ini memiliki dua alamat yang efektif, debugger menampilkan alamat pertama.

$ea 2

Alamat efektif kedua dari instruksi terakhir yang dijalankan. Jika instruksi ini tidak memiliki dua alamat yang efektif, debugger menampilkan "Kesalahan pendaftaran buruk".

$exp

Ekspresi terakhir yang dievaluasi.

$ra

Alamat pengembalian yang saat ini ada di tumpukan.

Alamat ini sangat berguna dalam perintah eksekusi. Misalnya, g @$ra berlanjut sampai alamat pengembalian ditemukan (meskipun gu (Go Up) adalah cara yang lebih tepat efektif untuk "melangkah keluar" dari fungsi saat ini).

$ip

Penunjuk instruksi mendaftar.

Prosesor berbasis x86: Sama seperti eip. Prosesor berbasis itanium: Terkait dengan iip. (Untuk informasi selengkapnya, lihat catatan setelah tabel ini.) Prosesor berbasis x64: Sama seperti sobek.

$eventip

Penunjuk instruksi pada saat peristiwa saat ini. Pointer ini biasanya cocok dengan $ip, kecuali Anda beralih utas atau mengubah nilai pointer instruksi secara manual.

$previp

Penunjuk instruksi pada saat peristiwa sebelumnya. (Memecah ke dalam debugger dihitung sebagai peristiwa.)

$relip

Penunjuk instruksi yang terkait dengan peristiwa saat ini. Ketika Anda melacak cabang, penunjuk ini adalah penunjuk ke sumber cabang.

$scopeip

Penunjuk instruksi untuk konteks lokal saat ini (juga dikenal sebagai cakupan).

$exentry

Alamat titik masuk dari executable pertama dari proses saat ini.

$retreg

Register nilai pengembalian utama.

Prosesor berbasis x86: Sama seperti eax. Prosesor berbasis itanium: Sama seperti ret0. Prosesor berbasis x64: Sama seperti rak.

$retreg 64

Register nilai pengembalian utama, dalam format 64-bit.

Prosesor x86: Sama seperti pasangan edx:eax .

$csp

Penunjuk tumpukan panggilan saat ini. Pointer ini adalah register yang paling mewakili kedalaman tumpukan panggilan.

Prosesor berbasis x86: Sama seperti esp. Prosesor berbasis itanium: Sama seperti bsp. Prosesor berbasis x64: Sama seperti rsp.

$p

Nilai yang dicetak oleh perintah d* (Memori Tampilan) terakhir.

$proc

Alamat proses saat ini (yaitu, alamat blok EPROCESS).

$thread

Alamat utas saat ini. Dalam penelusuran kesalahan mode kernel, alamat ini adalah alamat blok ETHREAD. Dalam penelusuran kesalahan mode pengguna, alamat ini adalah alamat blok lingkungan utas (TEB).

$peb

Alamat blok lingkungan proses (PEB) dari proses saat ini.

$teb

Alamat blok lingkungan utas (TEB) dari utas saat ini.

$tpid

ID proses (PID) untuk proses yang memiliki utas saat ini.

$tid

ID utas untuk utas saat ini.

$dtid

$dpid

$dsid

Nomor$bp

Alamat titik henti yang sesuai. Misalnya, $bp 3 (atau $bp 03) mengacu pada titik henti yang ID titik hentinya adalah 3. Angka selalu berupa angka desimal. Jika tidak ada titik henti yang memiliki ID Angka, $bpAngka mengevaluasi ke nol. Untuk informasi selengkapnya tentang titik henti, lihat Menggunakan Titik Henti.

$frame

Indeks bingkai saat ini. Indeks ini adalah nomor bingkai yang sama dengan yang digunakan perintah .frame (Atur Konteks Lokal ).

$dbgtime

Waktu saat ini, sesuai dengan komputer tempat debugger dijalankan.

$callret

Nilai yang dikembalikan dari fungsi terakhir yang dipanggil .call (Fungsi Panggilan) atau yang digunakan dalam perintah .fnret /s . Jenis data $callret adalah jenis data dari nilai yang dikembalikan ini.

$extret

$extin

$clrex

$lastclrex

Penelusuran kesalahan terkelola saja: Alamat objek pengecualian runtime bahasa umum (CLR) yang terakhir ditemui.

$ptrsize

Ukuran pointer. Dalam mode kernel, ukuran ini adalah ukuran penunjuk pada komputer target.

$pagesize

Jumlah byte dalam satu halaman memori. Dalam mode kernel, ukuran ini adalah ukuran halaman pada komputer target.

$pcr

$pcrb

$argreg

$exr_chance

Kemungkinan rekaman pengecualian saat ini.

$exr_code

Kode pengecualian untuk rekaman pengecualian saat ini.

$exr_numparams

Jumlah parameter dalam rekaman pengecualian saat ini.

$exr_param0

Nilai Parameter 0 dalam rekaman pengecualian saat ini.

$exr_param1

Nilai Parameter 1 dalam rekaman pengecualian saat ini.

$exr_param2

Nilai Parameter 2 dalam rekaman pengecualian saat ini.

$exr_param3

Nilai Parameter 3 dalam rekaman pengecualian saat ini.

$exr_param4

Nilai Parameter 4 dalam rekaman pengecualian saat ini.

$exr_param5

Nilai Parameter 5 dalam rekaman pengecualian saat ini.

$exr_param6

Nilai Parameter 6 dalam rekaman pengecualian saat ini.

$exr_param7

Nilai Parameter 7 dalam rekaman pengecualian saat ini.

$exr_param8

Nilai Parameter 8 dalam rekaman pengecualian saat ini.

$exr_param9

Nilai Parameter 9 dalam rekaman pengecualian saat ini.

$exr_param10

Nilai Parameter 10 dalam rekaman pengecualian saat ini.

$exr_param11

Nilai Parameter 11 dalam rekaman pengecualian saat ini.

$exr_param12

Nilai Parameter 12 dalam rekaman pengecualian saat ini.

$exr_param13

Nilai Parameter 13 dalam rekaman pengecualian saat ini.

$exr_param14

Nilai Parameter 14 dalam rekaman pengecualian saat ini.

$bug_code

Jika pemeriksaan bug telah terjadi, ini adalah kode bug. Berlaku untuk debugging mode kernel langsung dan crash dump kernel.

$bug_param1

Jika pemeriksaan bug telah terjadi, ini adalah nilai Parameter 1. Berlaku untuk debugging mode kernel langsung dan crash dump kernel.

$bug_param2

Jika pemeriksaan bug telah terjadi, ini adalah nilai Parameter 2. Berlaku untuk debugging mode kernel langsung dan crash dump kernel.

$bug_param3

Jika pemeriksaan bug telah terjadi, ini adalah nilai Parameter 3. Berlaku untuk debugging mode kernel langsung dan crash dump kernel.

$bug_param4

Jika pemeriksaan bug telah terjadi, ini adalah nilai Parameter 4. Berlaku untuk debugging mode kernel langsung dan crash dump kernel.

Beberapa pseudo-register ini mungkin tidak tersedia dalam skenario debugging tertentu. Misalnya, Anda tidak dapat menggunakan $peb, $tid, dan $tpid saat Men-debug minidump mode pengguna atau file cadangan mode kernel tertentu. Akan ada situasi di mana Anda dapat mempelajari informasi utas dari ~ (Status Utas) tetapi tidak dari $tid. Anda tidak dapat menggunakan pseudo-register $previp pada peristiwa debugger pertama. Anda tidak dapat menggunakan pseudo-register $relip kecuali Anda adalah pelacakan cabang. Jika Anda menggunakan pseudo-register yang tidak tersedia, kesalahan sintaks terjadi.

Pseudo-register yang menyimpan alamat struktur -- seperti $thread, $proc, $teb, $peb, dan $lastclrex -- akan dievaluasi sesuai dengan jenis data yang tepat dalam evaluator ekspresi C++, tetapi tidak dalam evaluator ekspresi MASM. Misalnya, perintah ? $teb menampilkan alamat TEB, sementara perintah ?? @$teb menampilkan seluruh struktur TEB. Untuk informasi selengkapnya, lihat Mengevaluasi Ekspresi.

Pada prosesor berbasis Itanium, register iipselaras dengan bundel, yang berarti menunjuk ke slot 0 dalam bundel yang berisi instruksi saat ini, bahkan jika slot yang berbeda sedang dijalankan. Jadi iip bukan penunjuk instruksi lengkap. Pseudo-register $ip adalah penunjuk instruksi aktual, termasuk bundel dan slot. Pseudo-register lainnya yang menyimpan pointer alamat ($ra, $retreg, $eventip, $previp, $relip, dan $exentry) memiliki struktur yang sama dengan $ip pada semua prosesor.

Anda dapat menggunakan perintah r untuk mengubah nilai $ip. Perubahan ini juga secara otomatis mengubah register yang sesuai. Saat eksekusi dilanjutkan, eksekusi dilanjutkan di alamat penunjuk instruksi baru. Register ini adalah satu-satunya pseudo-register otomatis yang dapat Anda ubah secara manual.

Catatan Dalam sintaks MASM, Anda dapat menunjukkan $ip pseudo-register dengan titik ( . ). Anda tidak menambahkan tanda (@) sebelum periode ini, dan jangan gunakan titik sebagai parameter pertama perintah r . Sintaks ini tidak diizinkan dalam ekspresi C++.

Pseudo-register otomatis mirip dengan alias otomatis. Tetapi Anda dapat menggunakan alias otomatis bersama dengan token terkait alias (seperti ${ }), dan Anda tidak dapat menggunakan pseudo-register dengan token tersebut.

Pseudo-Registers yang Ditentukan Pengguna

Ada 20 pseudo-register yang ditentukan pengguna ($t 0, $t 1, ..., $t 19). Pseudo-register ini adalah variabel yang dapat Anda baca dan tulis melalui debugger. Anda dapat menyimpan nilai bilangan bulat apa pun di pseudo-registers ini. Mereka dapat sangat berguna sebagai variabel perulangan.

Untuk menulis ke salah satu pseudo-register ini, gunakan perintah r (Registers), seperti yang ditunjukkan contoh berikut.

0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)

Seperti semua pseudo-register, Anda dapat menggunakan pseudo-register yang ditentukan pengguna dalam ekspresi apa pun, seperti yang ditunjukkan contoh berikut.

0:000> bp $t3 
0:000> bp @$t4 
0:000> ?? @$t1 + 4*@$t2 

Pseudo-register selalu diketik sebagai bilangan bulat, kecuali Anda menggunakan tombol ? bersama dengan perintah r . Jika Anda menggunakan sakelar ini, pseudo-register memperoleh jenis apa pun yang ditetapkan untuknya. Misalnya, perintah berikut menetapkan jenis UNICODE_STRING** dan nilai 0x0012FFBC ke $t 15.

0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc

Pseudo-register yang ditentukan pengguna menggunakan nol sebagai nilai default saat debugger dimulai.

Catatan Alias $u 0, $u 1, ..., $u 9 bukan pseudo-register, meskipun penampilannya mirip. Untuk informasi selengkapnya tentang alias ini, lihat Menggunakan Alias.

Contoh

Contoh berikut mengatur titik henti yang ditemui setiap kali utas saat ini memanggil NtOpenFile. Tetapi titik henti ini tidak terpukul ketika utas lain memanggil NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

Contoh

Contoh berikut menjalankan perintah hingga register menyimpan nilai yang ditentukan. Pertama, letakkan kode berikut untuk langkah bersyarah dalam file skrip bernama "eaxstep".

.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }

Selanjutnya, terbitkan perintah berikut.

t "$<eaxstep"

Debugger melakukan langkah lalu menjalankan perintah Anda. Dalam hal ini, debugger menjalankan skrip, yang menampilkan 1234 atau mengulangi proses.