如何查看 C++ 程序的汇编代码?

Posted

技术标签:

【中文标题】如何查看 C++ 程序的汇编代码?【英文标题】:How can I see the assembly code for a C++ program? 【发布时间】:2010-10-24 19:54:05 【问题描述】:

有哪些流行的工具可以做到这一点?

【问题讨论】:

Microsoft Visual C++ Express 只需设置断点并按Alt +8 可能重复: ***.com/questions/137038/… 相关:How to remove "noise" from GCC/clang assembly output? 包括创建简单函数的技巧,这些函数的 asm 看起来很有趣(例如函数 args 而不是常量),以及指向 Matt Godbolt 的 CppCon 的链接,讨论在编译器中寻找什么输出。 【参考方案1】:

询问编译器

如果您自己构建程序,您可以要求您的编译器发出汇编源代码。对于大多数 UNIX 编译器,使用 -S 开关。

如果您使用 GNU 汇编器,使用 -g -Wa,-alh 编译将在标准输出上提供混合的源代码和汇编(-Wa 要求编译器驱动程序将选项传递给汇编器,-al 打开汇编列表,-ah 添加“高级来源”列表):

g++ -g -c -Wa,-alh foo.cc

对于 Visual Studio,请使用 /FAsc

查看二进制文件

如果您有已编译的二进制文件,

在 UNIX 上使用 objdump -d a.out(也适用于 cygwin), dumpbin /DISASM foo.exe 在 Windows 上。

使用您的调试器

调试器也可以显示反汇编。

在 GDB 中使用 disas 命令。 如果您更喜欢 Intel 语法,请使用 set disassembly-flavor intel。 或 Windows 上 Visual Studio 的 disassembly window。

【讨论】:

我输入了 disas 命令,它成功了!.. 但你能告诉我如何在 Intel 语法中看到它吗? 注意objdump -drwC -S也可以混源+asm反汇编:Using GCC to produce readable assembly?。另外,How to remove "noise" from GCC/clang assembly output? 了解更多关于从gcc -O2 -S 获得良好输出的信息【参考方案2】:

这个网站目前正在为我工​​作(2017 年):https://godbolt.org/

【讨论】:

【参考方案3】:

你也可以试试这个网站:http://assembly.ynh.io/

在那里,您可以粘贴您的 C 或 C++ 代码,然后按蓝色按钮查看程序集等效版本。

【讨论】:

仅供参考,加载失败 是的,早在 2015 年它运行良好,然后突然停止。然后是 ctoassembly.com,但它只适用于 C 的一小部分。同样的事情发生了:不再加载。太糟糕了。【参考方案4】:

如果您是 Eclipse 用户,可以使用Disassembly view。

反汇编视图将加载的程序显示为汇编程序 指令与源代码混合用于比较。目前的 执行行由箭头标记指示,并在 看法。您可以在反汇编视图中执行以下任务:

在任何汇编指令的开头设置断点 启用和禁用断点并设置它们的属性 逐步执行程序的反汇编指令 跳转到程序中的特定指令

【讨论】:

你能详细说明一下吗? 在MSVC中调试时还有汇编视图 我现在没有可用的 Eclipse C++ 开发环境,但这里是官方文档:help.eclipse.org/kepler/…【参考方案5】:

在 Intel Mac OS X 10.8 (Mountain Lion) 上,-masm=intel 指令不起作用。但是,如果你安装了Xcode,它应该已经安装了名为'otool'的工具:

otool code.o -tV

您必须提供已编译的目标代码作为参数。

【讨论】:

【参考方案6】:

无论您使用什么调试器,都应该有一个汇编视图(Visual Studio、Borland IDE、gdb 等)。如果您没有使用调试器,而只想查看程序中的程序集,则可以使用反汇编程序,或者运行程序并使用调试器附加到它,然后从那里进行转储。有关选项的信息,请参阅对 disassemblers 的引用。

【讨论】:

【参考方案7】:

对于 gcc/g++

gcc -save-temps -fverbose-asm prog.c

这将在每个 asm 行中使用的变量上生成带有一些 cmets 的 prog.s:

    movl    $42, -24(%ebp)  #, readme
    movl    -16(%ebp), %eax # pid, pid
    movl    %eax, 4(%esp)   # pid,
    movl    $.LC0, (%esp)   #,
    call    printf  #

【讨论】:

【参考方案8】:

PE Explorer Disassembler 用于 32 位 PE 文件。其他人的 IDA。

【讨论】:

【参考方案9】:

在 GCC/G++ 中,使用 -S 编译。这将输出带有汇编代码的something.s 文件。

编辑:如果您希望输出采用 Intel 语法(这是 IMO,更具可读性,并且大多数汇编教程都使用它),请使用 -masm=intel 编译。

【讨论】:

添加-fverbose-asm选项【参考方案10】:

很多人已经告诉过如何使用给定的编译器生成汇编代码。另一种解决方案是编译一个目标文件并使用objdump、readelf(在 Unix 上)或 DUMPBIN(link)(在 Windows 上)等工具转储它。 您也可以转储一个可执行文件,但读取输出会更加困难。

这具有与任何编译器以相同方式工作的优点。

【讨论】:

【参考方案11】:

在 Visual Studio 中,您可以为 C++ 项目生成汇编程序列表。

转到项目属性,然后转到 C++/Output Files 并将 Assembler 输出设置和 ASM 列表位置设置为文件名。

【讨论】:

【参考方案12】:

大多数编译器都有输出汇编列表的选项。例如。使用 VisualStudio,您可以使用以下内容:

cl.exe /FAfile.asm file.c

不过,为了获得最佳可读性,大多数调试器都会提供一个将反汇编与原始源代码交错的视图,因此您可以逐行比较您的代码与编译器的输出。

【讨论】:

【参考方案13】:

在 Visual Studio 中

    设置断点 运行程序直到它在断点处停止 右键单击源代码并选择“显示分解”

【讨论】:

【参考方案14】:

正如其他人所提到的,您平台的调试器是一个很好的起点。所有调试器和反汇编器的手提钻,看看IDA Pro.

在 Unix/Linux 平台(包括 Cygwin)上,您可以使用 objdump --disassemble <executable>

【讨论】:

如果有一个选项可以让编译器生成汇编程序(如 gcc -S 或下面的 VS /FA 选项),这比反汇编更可取。它更具象征意义。 当然,如果你有来源。 顺便说一句,您会惊讶于 IDA Pro 可以推断出多少符号信息。

以上是关于如何查看 C++ 程序的汇编代码?的主要内容,如果未能解决你的问题,请参考以下文章

经验分享如何查看C++生成的汇编代码?

如何读取 Visual C++ 2010 生成的程序集输出?

VS Code 是不是有用于 C++ 扩展的内存查看器和/或反汇编器?

如何使用 g++ 获取 C++ 头文件 (.hpp) 的汇编代码?

在VS如何查看汇编代码

keil查看汇编代码