Debugging Tools for Windows

地址和地址范围语法

有几种方法在调试器中指定地址。

除非特别说明,否则地址总是虚拟地址。在用户模式下,虚拟地址根据当前进程的页目录来解析。在内核模式下,虚拟地址根据进程上下文(process context)指定进程的页目录来解析。也可能直接设置用户模式地址上下文(user-mode address context)。关于用户模式地址上下文的更多信息,查看.context (Set User-Mode Address Context)

地址模式和段支持

在 x86 平台上,CDB 和 KD 支持两种地址模式。通过前缀区分这两种模式

前缀 名字 地址类型
% flat 32 位地址(也可以是 16 位选择子指向 32 位段)和64位系统上的64位地址。
& virtual 86 实模式地址 - 仅针对 x86。
# plain 实模式地址。仅针对x86。

virtual 86模式和plain模式的区别在于plain 的16位地址将段值作为选择子用来查找段描述符。但是virtual 86地址不使用选择子而是直接映射到低1 MB内存。

如果你使用非当前缺省的地址模式存取内存,可以使用地址模式前缀掩盖当前的地址模式。

地址参数(Address Arguments)

地址参数指定变量和函数的位置。下表解释了在 CDB 和 KD 中使用的各种地址的语法和含义。

语法 含义
offset 虚拟内存空间的绝对地址,具有和当前执行模式匹配的类型。例如,如果当前执行模式是16位,则偏移是16位。如果当前执行模式是32位,则偏移是32位。
&[[ segment:]] offset 实地址。x86和x64。
%segment:[[ offset]] 分段的32位或64位地址。x86和x64。
%[[ offset]] 虚拟内存空间的绝对地址(32位或64位)。x86和x64。
name[[ +|]] offset 32位或64位平坦地址。name可以是任意符号。offset指定偏移。偏移可以由不同的前缀来表示不同的地址模式。不带前缀表示使用默认地址模式。可以指定正(+)偏移或负()偏移。

使用dg (Display Selector)命令查看段描述符(segment descriptor)信息。

在 MASM 表达式中,你也可以用 poi 运算符取任意指针指向的值。例如,如果地址 0x00123456 处的指针指向地址 0x00420000,下面两条命令等效:

0:000> dd 420000 
0:000> dd poi(123456) 

在 C++ 表达式中,指针行为就像 C++ 中一样。然而,数值被解析为整数,所以,如果你需要取一个数值指向的值,需要先把该数值强制转换为指针:

0:000> dd *( (long*) 0x123456 ) 

也有许多伪寄存器保存着常用的地址,像当前程序地址计数等。

也可以使用原始源文件名和行数指定程序中的一个地址。详细请看源码行语法

地址范围

有两种方法可以指定一个地址范围:一对地址,或者一个地址和一个对象数目(object count)。

要使用第一种方法,需要指定起始地址和结束地址。例如,下面是一个从 0x00001000 地址开始的 8 字节的范围。

0x00001000  0x00001007

第二种形式包括一个地址参数,字母 L(大小写都行)和一个数值参数。地址指定起始地址;数值指定要检查或显示的对象的数目。依根据命令不同对象大小也不一样。例如,如果对象大小是 1 字节,下面是一个从 0x00001000 地址开始的 8 字节的范围。

0x00001000  L8

然而,如果对象大小是一个 双字(32 位或者 4 字节),下面两个都给出了 8 字节的范围:

0x00001000  0x00001007
0x00001000  L2

还有另外两种方法用来指定范围(LSize范围指示符):

某些命令需要地址范围时也接受单个地址作为参数。这种情况下,该命令将使用某些缺省的对象数目来计算范围大小。典型的,那些地址范围是最后一个参数的命令将接受这种语法。参考单个命令说明得到准确的语法和每个命令的缺省范围大小。

Build machine: CAPEBUILD