Debugging Tools for Windows |
MASM(Microsoft 宏汇编器)表达式语法是 Debugging Tools for Windows 4.0 之前版本中的 NTSD, CDB, KD 和 WinDbg 惟一使用的语法。
MASM 表达式中的数值能够以 16, 10, 8 或者 2 为基数方式输入。
n (Set Number Base)命令可用来设置缺省基数为 16, 10 或者 8。所有不带前缀的数值都以该基数来解释。通过指定 0x 前缀(十六进制),0n 前缀(十进制),0t 前缀(八进制),或者 0y 前缀(二进制)能够掩盖缺省基数。
也可以添加一个 h 后缀表示十六进制数值。数值里面的字母可以是大写或者小写,所以 "0x4AB3", "0X4aB3", "4AB3h", "4ab3h" "4aB3H" 都表示相同意思。
如果表达式中前缀后面没有跟一个数值,它被读作 0。所以,0 可以写成三种形式:0,前缀后面跟一个 0,单独一个前缀。例如,在十六进制下,"0", "0x0" 和 "0x" 都表示相同意思。
能够以 xxxxxxxx`xxxxxxxx 格式输入 64 位的十六进制数值,或者忽略当中的重音符号(`)。包含重音符号会使得自动符号扩展无效。
在 MASM 表达式中,任意符号的数值都是它的内存地址。根据引用符号的不同,可以是全局变量、局部变量、函数、段、模块或者任何其它可识别标签的地址。
可以通过在富豪名前面加上模块名和一个感叹号( ! )前缀来指明地址关联到的模块。如果符号可能被解释成一个16进制数字,可以加上模块名和感叹号前缀,也可以只使用感叹号。关于符号识别,详细请看符号语法和符号匹配。
两个冒号(::)或者两条下划线(__)可以用来标志类的成员。
只有以模块名和感叹号为前缀的符号名中才能使用重音符号(`)或者撇号(')。
表达式的任意组件都可以用一元运算符来修改,任意两个组件都可以用二元运算符组合起来。一元运算符优先于二元运算符。当用到多个二元运算符时,遵循下面表格中描述的已定的优先级规则。
总是可以用圆括号来掩盖优先级规则。
如果 MASM 表达式的某一部分被圆括号括住并有两个 @ 前缀 (@@ ) ,该部分将根据C++ 表达式规则来解析。在两个 @ 记号之间以及和左圆括号之间不能有空格。也可以通过使用 @@c++( ... ) 或者 @@masm( ... ) 指定表达式求值器。
当执行算术运算时,MASM 表达式求解器把所有的数值和符号当做 ULONG64 类型。
一元地址运算符寻址时假定 DS 为缺省段。按运算符的优先级顺序计算表达式。如果两个相邻的运算符优先级一样,则从左往右计算表达式。
一元运算符有:
运算符 | 含义 |
---|---|
+ | 正数 |
- | 负数 |
not | 如果参数为零返回 1;任何非零参数返回 0。 |
hi | 高 16 位 |
low | 低 16 位 |
by | 指定地址处的低位字节 |
$pby | 除了接受的为物理内存地址之外,和by一样。只能读取使用默认的缓存行为的物理内存。 |
wo | 指定地址处的低位字 |
$pwo | 除了限制为物理内存地址之外,和wo一样。只能读取使用默认的缓存行为的物理内存。 |
dwo | 指定地址处的双字。 |
$pdwo | 除了限制为物理内存地址之外,和dwo一样。只能读取使用默认的缓存行为的物理内存。 |
qwo | 指定地址处的四字节。 |
$pqwo | 除了限制为物理内存地址之外,和qwo一样。只能读取使用默认的缓存行为的物理内存。 |
poi | 指定地址处的指针大小的数据。指针大小或者是 32 位或者是 64 位。在内核调试模式,大小基于目标计算机上的处理器。在 Intel Itanium 计算机上用户模式调试下,大小或者是 32 位或者是 64 位,依赖于目标应用程序。所以,如果你想得到指针大小的数据最好使用 poi 运算符。 |
$ppoi | 除了限制为物理内存地址之外,和poi一样。只能读取使用默认的缓存行为的物理内存。 |
可以使用下表中列出的二元运算符。每个单元格中的运算符优先级从上往下依次降低。同一格的各个运算符优先级相同,以从左往右的方式计算。
操作符 | 含义 |
---|---|
* / mod (或 %) |
乘法 整数除法 模数(余数) |
+ - |
加法 减法 |
<< >> >>> |
左移位 逻辑右移位 算术右移位 |
= (or ==) < > <= >= != |
等于 小于 大于 小于等于 大于等于 不等于 |
and (或&) | 按位与 |
xor (或^) | 按位异或(不同于 OR) |
or (或|) | 按位或 |
比较运算符 <, >, =, == 和 != 计算后如果为真则得到 1,如果为假则得到 0。单个等于号(=)和双等于号(==)相同;在 MASM 表达式中不会产生副作用,也不会赋值。
非法操作(例如除零)会返回给调试器命令窗口调试器命令窗口一个"Operand error"。
下表列出了可在 MASM 表达式中使用的其它运算符。
操作符 | 含义 |
---|---|
$fnsucc(FnAddress, RetVal, Flag) | 将RetVal作为位于FnAddress处的函数地返回值。如果返回值是一个成功码,$fnsucc
返回 TRUE,否则返回 FALSE。 如果返回值类型是 BOOL、 bool、 HANDLE、 HRESULT 或者 NTSTATUS,$fnsucc 可以正确理解指定的返回值是否一个成功码。如果返回值类型是一个指针,所有 NULL 以外的值都是成功码。对于其它返回值类型,根据 Flag 值来定义成功与否,如果 Flag 是 0,那么一个非零 RetVal 值表示成功;如果 Flag 是 1,则 RetVal 值为 0 表示成功。 |
$iment (Address) | 返回加载模块列表中映像入口点地址。Address 指定 PE 映像基地址。通过查找 Address
指定映像的 PE 头中的映像入口点找到入口点。 该函数既可以用在模块列表中已有的模块上,也可以通过bu命令设置未确定的断点。 |
$scmp("String1", "String2") | 计算后得到 -1、0 或者 1;就像 C 函数中的 strcmp。 |
$sicmp("String1", "String2") | 计算后得到 -1、0 或者 1;就像 Win32 函数 stricmp。 |
$spat("String", "Pattern") | 根据 String 是否匹配 Pattern 计算得到 TRUE 或 FALSE。Pattern 可以包含多种通配符和特定符(specifiers);详细请看 字符串通配符语法。 |
$vvalid(Address, Length) | 判断一段起始地址为 Address 长度为 Length字节的内存范围是否有效。如果这段内存有效,$vvalid 计算得到 1;否则,$vvalid 计算得到 0。 |
MASM 表达式中可以使用寄存器和伪寄存器。所有寄存器和伪寄存器可以包含单个at符号( @) 的前缀。使用该前缀可以使调试器存取这些值更快。该记号对于大多数 x86 通用寄存器不需要。对于其它寄存器和伪寄存器实际上也不是必须的,但强烈建议使用。对于少数通用寄存器如果忽略该前缀,调试器首先会尝试解释该文本为十六进制数值,然后解释为符号,最后才把它解释为寄存器。
你也能用一个点号(.)表示当前指令指针。该点号不能带 @ 前缀,不能用作 r 命令的第一个参数。该点号和 $ip 伪寄存器含义相同。
MASM 表达式中可以使用源代码文件和行数表达式。必须用重音符号(`)把它们括住。详细请看源码行语法。