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内存。
如果你使用非当前缺省的地址模式存取内存,可以使用地址模式前缀掩盖当前的地址模式。
地址参数指定变量和函数的位置。下表解释了在 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 poi(123456)
在 C++ 表达式中,指针行为就像 C++ 中一样。然而,数值被解析为整数,所以,如果你需要取一个数值指向的值,需要先把该数值强制转换为指针:
也有许多伪寄存器保存着常用的地址,像当前程序地址计数等。
也可以使用原始源文件名和行数指定程序中的一个地址。详细请看源码行语法。
有两种方法可以指定一个地址范围:一对地址,或者一个地址和一个对象数目(object count)。
要使用第一种方法,需要指定起始地址和结束地址。例如,下面是一个从 0x00001000 地址开始的 8 字节的范围。
第二种形式包括一个地址参数,字母 L(大小写都行)和一个数值参数。地址指定起始地址;数值指定要检查或显示的对象的数目。依根据命令不同对象大小也不一样。例如,如果对象大小是 1 字节,下面是一个从 0x00001000 地址开始的 8 字节的范围。
然而,如果对象大小是一个 双字(32 位或者 4 字节),下面两个都给出了 8 字节的范围:
0x00001000 L2
还有另外两种方法用来指定范围(LSize范围指示符):
某些命令需要地址范围时也接受单个地址作为参数。这种情况下,该命令将使用某些缺省的对象数目来计算范围大小。典型的,那些地址范围是最后一个参数的命令将接受这种语法。参考单个命令说明得到准确的语法和每个命令的缺省范围大小。