在程序集模式下调试

如果有应用程序的 C 或 C++ 源文件,如果在 源模式下进行调试,则可以更强大的使用调试器。

但是,很多时候你无法执行源调试。 可能没有应用程序的源文件。 你可能在调试其他人的代码。 你可能没有使用完整的 .pdb 符号生成可执行文件。 即使可以对应用程序执行源调试,也可能必须跟踪应用程序调用或用于加载应用程序的 Microsoft Windows 例程。

在这些情况下,必须在程序集模式下进行调试。 此外,程序集模式具有许多在源调试中不存在的有用功能。 调试器会在访问内存位置时自动显示内存位置的内容和寄存器,并显示程序计数器的地址。 此显示使程序集调试成为可与源调试一起使用的宝贵工具。

反汇编代码

调试器主要分析二进制可执行代码。 调试器不以原始格式显示此代码,而是 反汇编 此代码。 也就是说,调试器将代码从计算机语言转换为汇编语言。

可以通过几种不同的方式显示生成的代码 (称为 反汇编代码) :

  • u (Unassemble) 命令反汇编并显示计算机语言的指定部分。

  • uf (Unassemble 函数) 命令反汇编并显示函数。

  • 向上 (从物理内存中取消汇编) 命令反汇编,并显示已存储在物理内存中的指定计算机语言部分。

  • (Unassemble Real Mode 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 的反汇编窗口中,突出显示表示当前程序计数器的行。 还突出显示了设置断点的行。

还可以使用以下命令操作程序集代码:

  • # (搜索反汇编模式) 命令在内存区域中搜索特定模式。 此命令等效于搜索反汇编显示的四列。

  • (Assemble) 命令可以接受程序集指令并将其转换为二进制计算机代码。

程序集模式和源模式

调试器有两种不同的操作模式: 程序集模式源模式

单步执行应用程序时,单步执行的大小是一行程序集代码或一行源代码,具体取决于模式。

多个命令根据模式创建不同的数据显示。

在 WinDbg 中,在程序集模式下运行或单步执行应用程序时, 反汇编窗口 会自动移动到前台。 在源模式下, “源”窗口 移动到前台。

若要设置模式,可以执行下列操作之一:

  • 使用 l+、l- (设置源选项) 命令来控制模式。 l-t 命令激活程序集模式。

  • (WinDbg 仅) “调试”菜单上的“清除源模式”命令,导致调试器进入程序集模式。还可以选择工具栏上的“源模式关闭”按钮。

在 WinDbg 中,处于程序集模式时, ASM 会显示在状态栏上。

WinDbg 反汇编窗口中的快捷菜单包括 当前源行命令中的“突出显示”指令 。 此命令突出显示与当前源行对应的所有指令。 通常,单个源行对应于多个程序集指令。 如果代码已优化,则这些程序集指令可能不是连续的。 使用 “突出显示当前源行中的指令 ”命令,可以查找从当前源行组装的所有指令。

程序集语言源文件

如果应用程序是使用汇编语言编写的,则调试器生成的反汇编可能与原始代码不完全匹配。 特别是,NO-OPs 和注释将不存在。

如果要通过引用原始 .asm 文件来调试代码,则必须使用源模式调试。 可以像 C 或 C++ 源文件一样加载程序集文件。 有关此类调试的详细信息,请参阅 在源模式下调试