如果您有应用程序的 C 或 C++ 源文件,那么在源模式下调试时可以更有效地使用调试器。
但是,很多时候无法执行源调试。 可能没有应用程序的源文件。 你可能正在调试其他人的代码。 你可能没有使用完整的 .pdb 符号生成可执行文件。 即使可以在您的应用程序上进行源调试,您可能需要跟踪您的应用程序调用的 Microsoft Windows 例程,或跟踪用于加载您的应用程序的例程。
在这些情况下,必须在程序集模式下进行调试。 此外,程序集模式具有许多在源调试中不存在的有用功能。 调试器在访问内存位置时,会自动显示其内容及寄存器的状态,并显示程序计数器的地址。 此显示使程序集调试成为一个有价值的工具,可与源调试一起使用。
反汇编代码
调试器主要分析二进制可执行代码。 调试器不以原始格式显示此代码,而是 反汇编 此代码。 也就是说,调试器将代码从计算机语言转换为程序集语言。
可以通过多种不同的方式显示生成的代码(称为 反汇编代码):
u (Unassemble) 命令反汇编并显示计算机语言的指定部分。
uf (Unassemble Function) 命令反汇编并显示函数。
up(从物理内存中反汇编)命令反汇编并显示已存储在物理内存中的机器语言的指定部分。
The ur(取消汇编实际模式 BIOS)命令可反汇编并显示指定的 16 位实模式代码。
ux(Unassemble x86 BIOS)命令反汇编,并在指定地址处显示基于 x86 的 BIOS 代码指令集。
(仅限 WinDbg)反汇编窗口反汇编并显示机器语言的指定部分。 如果选择窗口菜单上的自动打开反汇编命令,则此窗口将自动处于活动状态。 还可以通过在视图菜单上选择反汇编、按 alt+7 或按反汇编(alt+7)按钮来打开此窗口。
反汇编显示出现在四列中:地址偏移量、二进制代码、汇编语言助记和汇编语言详细信息。 以下示例显示此显示。
0040116b 45 inc ebp
0040116c fc cld
0040116d 8945b0 mov eax,[ebp-0x1c]
在表示当前程序计数器的行右侧,显示要访问的任何内存位置或寄存器的值。 如果此行包含分支指令,将显示表示法 [br=1] 或 [br=0]。 此符号分别表示一个分支被占用或未被占用。
可以使用 .asm (更改反汇编选项) 命令更改反汇编指令的显示方式。
在 WinDbg 的反汇编视图中,表示当前程序计数器的行将突出显示。 设置了断点的行也会突出显示。
还可以使用以下命令操作程序集代码:
#(搜索反汇编模式)命令搜索特定模式的内存区域。 此命令相当于搜索反汇编显示的四列。
a(汇编)命令可以接受汇编指令并将其转换为二进制机器代码。
程序集模式和源模式
调试器具有两种不同的作模式: 程序集模式 和 源模式。
单步执行应用程序时,单个步骤的大小是一行程序集代码或一行源代码,具体取决于模式。
根据不同的模式,多个命令会创建不同的数据展示。
在 WinDbg 中,当你在汇编模式下运行或单步执行应用程序时,反汇编窗口会自动移动到前台。 在源模式下, “源”窗口 将移动到前台。
若要设置模式,可以执行下列作之一:
使用 l+、l- (设置源选项) 命令控制模式。 l-t 命令激活程序集模式。
(仅限 WinDbg)清除“调试”菜单上的“源模式”命令,使调试器进入程序集模式。还可以选择工具栏上的“源模式关闭”按钮。
在 WinDbg 中,处于程序集模式时, ASM 显示在状态栏上。
WinDbg 的反汇编窗口中的快捷菜单包括突出显示当前源代码行中的指令命令。 此命令突出显示与当前源行对应的所有说明。 通常,单个源行对应于多个程序集指令。 如果代码已优化,则这些程序集指令可能不是连续的。 通过 当前源行命令中的突出显示指令 ,可以找到从当前源行组装的所有指令。
汇编语言源文件
如果应用程序是使用程序集语言编写的,则调试器生成的反汇编可能与原始代码不完全匹配。 具体而言,NO-OPs 和注释将不存在。
如果要通过引用原始 .asm 文件来调试代码,则必须使用源模式调试。 可以加载程序集文件(如 C 或C++源文件)。 有关此类调试的详细信息,请参阅 源模式下的调试。