|
http://msdn.microsoft.com/en-us/library/cc266544.aspx Debugging Tools for Windows
Pseudo-Register Syntax
The debugger supports several pseudo-registers that hold certain values. The debugger sets automatic pseudo-registers to certain useful values. User-defined pseudo-registers are integer variables that you can write to or read. All pseudo-registers begin with a dollar sign ($). If you are using MASM syntax, you can add an at sign ( @ ) before the dollar sign. This at sign tells the debugger that the following token is a register or pseudo-register, not a symbol. If you omit the at sign, the debugger responds more slowly, because it has to search the whole symbol table. For example, the following two commands produce the same output, but the second command is faster. 0:000> ? $exp If a symbol exists with the same name as the pseudo-register, you must add the at sign. If you are using C++ _expression_ syntax, the at sign ( @ ) is always required. The r (Registers) command is an exception to this rule. The debugger always interprets its first argument as a register or pseudo-register. (An at sign is not required or permitted.) If there is a second argument for the r command, it is interpreted according to the default _expression_ syntax. If the default _expression_ syntax is C++, you must use the following command to copy the $t2 pseudo-register to the $t1 pseudo-register. 0:000> r $t1 = @$t2 Automatic Pseudo-RegistersThe debugger automatically sets the following pseudo-registers.
Some of these pseudo-registers might not be available in certain debugging scenarios. For example, you cannot use $peb, $tid, and $tpid when you are debugging a user-mode minidump or certain kernel-mode dump files. There will be situations where you can learn thread information from ~ (Thread Status) but not from $tid. You cannot use the $previp pseudo-register on the first debugger event. You cannot use the $relip pseudo-register unless you are branch tracing. If you use an unavailable pseudo-register, a syntax error occurs. A pseudo-register that holds the address of a structure ― such as $thread, $proc, $teb, $peb, and $lastclrex ― will be evaluated according to the proper data type in the C++ _expression_ evaluator, but not in the MASM _expression_ evaluator. For example, the command ? $teb displays the address of the TEB, while the command ?? @$teb displays the entire TEB structure. For more information, see Evaluating Expressions. On an Itanium-based processor, the iip register is bundle-aligned, which means that it points to slot 0 in the bundle containing the current instruction, even if a different slot is being executed. So iip is not the full instruction pointer. The $ip pseudo-register is the actual instruction pointer, including the bundle and the slot. The other pseudo-registers that hold address pointers ($ra, $retreg, $eventip, $previp, $relip, and $exentry) have the same structure as $ip on all processors. You can use the r command to change the value of $ip. This change also automatically changes the corresponding register. When execution resumes, it resumes at the new instruction pointer address. This register is the only automatic pseudo-register that you can change manually. Note In MASM syntax, you can indicate the $ip pseudo-register with a period ( . ). You do not add an at sign (@) before this period, and do not use the period as the first parameter of the r command. This syntax is not permitted within a C++ _expression_. Automatic pseudo-registers are similar to automatic aliases. But you can use automatic aliases together with alias-related tokens (such as ${ }), and you cannot use pseudo-registers with such tokens. User-Defined Pseudo-RegistersThere are 20 user-defined pseudo-registers ($t0, $t1, ..., $t19). These pseudo-register are variables that you can read and write through the debugger. You can store any integer value in these pseudo-registers. They can be especially useful as loop variables. To write to one of these pseudo-registers, use the r (Registers) command, as the following example shows. 0:000> r $t0 = 7 Like all pseudo-registers, you can use the user-defined pseudo-register in any _expression_, as the following example shows. 0:000> bp $t3 A pseudo-register is always typed as an integer, unless you use the ? switch together with the r command. If you use this switch, the pseudo-register acquires the type of whatever is assigned to it. For example, the following command assigns the UNICODE_STRING** type and the 0x0012FFBC value to $t15. 0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc User-defined pseudo-registers use zero as the default value when the debugger is started. Note The aliases $u0, $u1, ..., $u9 are not pseudo-registers, despite their similar appearance. For more information about these aliases, see Using Aliases. ExampleThe following example sets a breakpoint that is hit every time that the current thread calls NtOpenFile. But this breakpoint is not hit when other threads call NtOpenFile. kd> bp /t @$thread nt!ntopenfile ExampleThe following example executes a command until the register holds a specified value. First, put the following code for conditional stepping in a script file named “eaxstep”. .if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" } Next, issue the following command. t "$<eaxstep" The debugger performs a step and then runs your command. In this case, the debugger runs the script, which either displays 1234 or repeats the process. Build machine: CAPEBUILD
|
