Bagikan melalui


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 @, 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 ada simbol dengan nama yang sama sebagai 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 menginterpretasikan 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 pseudoregister berikut.

Pseudo-register (register palsu) Deskripsi

$ea

Alamat efektif dari instruksi terakhir yang telah dijalankan. Jika instruksi ini tidak memiliki alamat yang efektif, debugger menampilkan "Kesalahan register 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 register tidak valid".

$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 (Naik) adalah cara yang lebih tepat untuk "keluar" dari fungsi saat ini).

$ip

Daftar penunjuk instruksi.

Prosesor berbasis x86: Sama seperti eip. Prosesor berbasis Itanium: Terkait dengan iip. (Untuk informasi selengkapnya, lihat catatan berikut tabel ini.) Prosesor berbasis x64: Sama seperti rip.

$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. (Memasuki debugger dianggap sebagai sebuah peristiwa.)

$relip

Penunjuk instruksi yang terkait dengan peristiwa saat ini. Ketika Anda melakukan penelusuran cabang, pointer ini adalah pointer ke sumber cabang.

$scopeip

Penunjuk instruksi untuk konteks lokal saat ini (juga disebut sebagai ruang lingkup).

$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. Penunjuk 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 perintah d* (Memori Tampilan) terakhir.

$proc

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

$thread

Alamat utas saat ini. Dalam debugging mode kernel, alamat ini adalah alamat blok ETHREAD. Dalam debugging user-mode, alamat ini adalah alamat thread environment block (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 thread untuk thread 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 angka desimal. Jika tidak ada titik henti yang memiliki ID Angka, $bpAngka bernilai 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 pengembalian fungsi terakhir yang dipanggil .call (Fungsi Panggilan) atau yang digunakan dalam perintah .fnret /s . Jenis data $callret adalah jenis data dari nilai pengembalian ini.

$extret

$extin

$clrex

$lastclrex

Hanya debugging terkelola: Alamat objek pengecualian bahasa umum runtime (CLR) yang terakhir ditemui.

$ptrsize

Ukuran penunjuk. 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

Peluang adanya rekaman pengecualian saat ini.

$exr_code

Kode pengecualian untuk catatan pengecualian yang saat ini.

$exr_numparams

Jumlah parameter dalam rekaman pengecualian saat ini.

$exr_param0

Nilai Parameter 0 pada catatan pengecualian saat ini.

$exr_param1

Nilai Parameter 1 di rekaman pengecualian saat ini.

$exr_param2

Nilai Parameter 2 dalam catatan pengecualian saat ini.

$exr_param3

Nilai Parameter 3 dalam catatan pengecualian terkini.

$exr_param4

Nilai Parameter 4 dalam catatan pengecualian saat ini.

$exr_param5

Nilai Parameter 5 dalam rekaman pengecualian saat ini.

$exr_param6

Nilai Parameter 6 dalam catatan pengecualian terbaru.

$exr_param7

Nilai Parameter 7 pada catatan pengecualian terkini.

$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 catatan pengecualian saat ini.

$exr_param11

Nilai Parameter 11 dalam rekaman pengecualian saat ini.

$exr_param12

Nilai dari Parameter 12 di dalam catatan pengecualian saat ini.

$exr_param13

Nilai Parameter 13 pada catatan 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 berfungsi dan dump kerusakan 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 Anda men-debug minidump mode pengguna atau file cadangan mode kernel tertentu. Akan ada situasi di mana Anda dapat mendapatkan informasi tentang utas dari ~ (Status Utas) namun tidak dari $tid. Anda tidak dapat menggunakan pseudo-register $previp pada peristiwa debugger pertama. Anda tidak dapat menggunakan pseudo-register $relip kecuali Anda melakukan penelusuran 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 pointer instruksi aktual, termasuk bundel dan slot. Pseudo-register lain 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 pseudoregister $ip dengan titik ( . ). Anda tidak menambahkan tanda (@) sebelum periode ini, dan jangan gunakan periode sebagai parameter pertama dari 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.

User-Defined Pseudo-Registers

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. Ini 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 sakelar ? bersama dengan perintah r . Jika Anda menggunakan pengalih ini, pseudo-register memperoleh jenis yang diberikan padanya. 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.

Nota 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 menetapkan titik henti yang diaktifkan setiap kali utas saat ini memanggil NtOpenFile. Tetapi titik henti ini tidak aktif ketika dipanggil oleh utas lain pada NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

Contoh

Contoh berikut menjalankan perintah hingga register menyimpan nilai tertentu. Pertama, letakkan kode berikut untuk langkah bersyarat dalam berkas 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.