Debugging Tools for Windows

MASM数值和运算符

MASM(Microsoft 宏汇编器)表达式语法是 Debugging Tools for Windows 4.0 之前版本中的 NTSD, CDB, KD 和 WinDbg 惟一使用的语法。

MASM 表达式中的数值

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 表达式中的符号

在 MASM 表达式中,任意符号的数值都是它的内存地址。根据引用符号的不同,可以是全局变量、局部变量、函数、段、模块或者任何其它可识别标签的地址。

可以通过在富豪名前面加上模块名和一个感叹号( ! )前缀来指明地址关联到的模块。如果符号可能被解释成一个16进制数字,可以加上模块名和感叹号前缀,也可以只使用感叹号。关于符号识别,详细请看符号语法和符号匹配

两个冒号(::)或者两条下划线(__)可以用来标志类的成员。

只有以模块名和感叹号为前缀的符号名中才能使用重音符号(`)或者撇号(')。

MASM 表达式中的数值运算符

表达式的任意组件都可以用一元运算符来修改,任意两个组件都可以用二元运算符组合起来。一元运算符优先于二元运算符。当用到多个二元运算符时,遵循下面表格中描述的已定的优先级规则。

总是可以用圆括号来掩盖优先级规则。

如果 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 表达式中的非数值运算符

下表列出了可在 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 表达式中的寄存器和伪寄存器

MASM 表达式中可以使用寄存器和伪寄存器。所有寄存器和伪寄存器可以包含单个at符号( @) 的前缀。使用该前缀可以使调试器存取这些值更快。该记号对于大多数 x86 通用寄存器不需要。对于其它寄存器和伪寄存器实际上也不是必须的,但强烈建议使用。对于少数通用寄存器如果忽略该前缀,调试器首先会尝试解释该文本为十六进制数值,然后解释为符号,最后才把它解释为寄存器。

你也能用一个点号(.)表示当前指令指针。该点号不能带 @ 前缀,不能用作 r 命令的第一个参数。该点号和 $ip 伪寄存器含义相同。

详细请看寄存器语法伪寄存器语法

MASM 表达式中的源代码行数

MASM 表达式中可以使用源代码文件和行数表达式。必须用重音符号(`)把它们括住。详细请看源码行语法

Build machine: CAPEBUILD