Logo
Section 1 / 3

GDB 汇编输出——无优化模式

学习如何在不进行代码优化的情况下编译、加载并执行 GDB 反汇编程序。

导入

GDB 汇编输出——无优化模式

学习如何在不进行代码优化的情况下编译、加载并执行 GDB 反汇编程序。

算术程序

让我们以一种在 C 和 C++ 中都能正常工作的形式重写我们的算术程序。对应的汇编语言指令已写在注释中:

1int a, b; 2int main(int argc, char* argv[]) 3{ 4 // 将值赋给变量 a 和 b 5 a = 1; // movl $1, a 6 b = 1; // movl $1, b 7 // 将 b 和 a 相加,结果存入变量 b 8 b = b + a; // mov a, %eax 9 // mov b, %edx 10 // add %edx, %eax 11 // mov %eax, b 12 // 将变量 a 的值加一 13 ++a; // mov a, %eax 14 // add $1, %eax 15 // mov %eax, a 16 // 将 a 与 b 相乘,结果存入 b 17 b = b * a; // mov b, %edx 18 // mov a, %eax 19 // imul %edx, %eax 20 // mov %eax, b 21 22 // 结果:(a) = 2 且 (b) = 4 23 // 返回 0 表示程序成功执行 24 return 0; 25}

无优化模式下的反汇编

在调试过程中,如果能不进行代码优化地重新编译,会更容易跟踪程序的运行进度。初始化 GDB 环境的步骤如下:

注意:你可以在本课末尾提供的编程沙箱中练习所有命令。

让我们以无优化模式(默认)进行编译和链接:

1gcc ArithmeticProjectC.cpp -o ArithmeticProjectC

这将生成一个可执行二进制文件,我们可以将其加载到 GDB 中检查汇编代码。

首先,使用程序作为参数运行 GDB:

1gdb ./ArithmeticProjectC

执行上述命令后,输出应如下所示:

...
加载目标代码到 GDB

接下来,我们在 C++ 的 main 函数中设置一个 breakpoint。这将在该点暂停程序执行,使我们有机会检查内存和寄存器。可以使用符号名或函数名(如 main)代替代码的内存地址:

1break main

在 GDB 环境中执行 break main 后,我们会得到如下结果:

...
创建断点

在启动调试程序之前,GDB 必须禁用 Linux 内核的地址空间随机化,以避免相同内存地址被重新分配。以下命令用于关闭此功能:

1set disable-randomization off

然后执行(run)程序。程序将在之前设置的断点处停止:

1run

我们可以预期得到如下结果:

...
开始执行

现在我们使用 disass 反汇编 main 函数:

1disass main

我们可以观察到如下输出:

...
反汇编 main 函数

现在我们重复显示与我们的 C++ 代码相对应的部分反汇编输出:

...
提取与我们的 C++ 程序对应的反汇编代码

我们可以直接将其转换为原始汇编代码,并在注释中添加相应的伪代码:

1movl $1, a # 1 -> (a) 2movl $1, b # 1 -> (b) 3mov b, %edx # (b) + (a) -> (b) 4mov a, %eax 5add %edx, %eax 6mov %eax, b 7mov a, %eax # (a) + 1 -> (a) 8add $1, %eax 9mov %eax, a 10mov b, %edx # (b) * (a) -> (b) 11mov a, %eax 12imul %edx, %eax 13mov %eax, b

现在我们可以退出 GDB:

1q

输入此命令后,将得到如下输出:

...
退出 GDB

命令总结

在本课中,我们学习了如何在不进行代码优化的情况下运行程序。为此,我们需要按以下顺序执行命令。

  1. 编译和链接程序的命令:
1gcc ArithmeticProjectC.cpp -o ArithmeticProjectC
  1. 启动 gdb 并加载程序的命令:
1gdb ./ArithmeticProjectC
  1. 在程序中插入断点的命令:
1break main
  1. 禁用程序地址空间随机化的命令:
1set disable-randomization off
  1. 执行程序的命令:
1run
  1. 反汇编程序的命令:
1disass main
  1. 退出当前函数的命令:
1finish
  1. 继续函数执行的命令:
1c
  1. 函数执行完成后,退出 GDB 环境:
1q

自行尝试

现在轮到你实践上述命令,查看 GDB 的反汇编输出。点击“运行”按钮,执行摘要中提到的命令。

No configuration found for ID: e0a2221639b32936a02accc9006839efdad115003faf43249a95aaca6b3c9d6f

内存、寄存器与简单算术

GDB 反汇编输出——优化模式