【问题标题】:Learning to read GCC assembler output学习阅读 GCC 汇编器输出
【发布时间】:2011-02-06 08:52:19
【问题描述】:

我正在考虑对组装进行一些非常基本的了解。我目前的目标很简单:非常基本在使用 x86/x86-64 的 -S 开关编译 C/C++ 时了解 GCC 汇编器输出。

只够做一些简单的事情,例如查看单个函数并验证 GCC 是否优化了我希望消失的东西。

是否有人拥有/知道关于汇编的真正简洁的介绍,与 GCC 相关并且专门用于阅读目的,以及任何随便阅读汇编的人都应该知道的最重要说明的列表?

【问题讨论】:

  • 您还没有指定您感兴趣的目标汇编语言。Intel x86?电源PC?

标签: c++ c gcc assembly


【解决方案1】:

您应该使用 GCC 的 -fverbose-asm 选项。它使编译器输出附加信息(以 cmets 的形式),从而更容易理解汇编代码与原始 C/C++ 代码的关系。

【讨论】:

    【解决方案2】:

    如果您使用 gcc 或 clang,-masm=intel 参数告诉编译器使用 Intel 语法而不是 AT&T 语法生成程序集,--save-temps 参数告诉编译器保存临时文件(预处理源,汇编输出,未链接的目标文件)在调用GCC的目录中。

    借助所有资源,对 x86 汇编有一个肤浅的了解应该很容易。这是一个这样的资源:@​​987654321@。

    您也可以只使用 disasm 和 gdb 来查看编译后的程序在做什么。

    【讨论】:

    • 如果你做 GDB 反汇编,你也可以使用 set disassembly-flavor intel 那里的 Intel 语法。
    【解决方案3】:

    我通常在面对新设备时查找处理器文档,然后在遇到我不知道的操作码时查找操作码。

    在 Intel 上,幸好操作码有些合理。在我看来,PowerPC 并没有那么多。 MIPS 是我的最爱。对于 MIPS,我借了邻居的小参考书,对于 PPC,我有一些 PDF 格式的 IBM 文档,便于搜索。 (而对于英特尔,我主要是猜测然后观察寄存器以确保我猜对了!呵呵)

    基本上,组装本身很容易。它基本上做了三件事:在内存和寄存器之间移动数据,对寄存器中的数据进行操作,以及更改程序计数器。您选择的语言和程序集之间的映射将需要一些研究(例如学习如何识别虚函数调用),为此,“集成”源代码和反汇编视图(就像您可以在 Visual Studio 中获得的那样)非常有用。

    【讨论】:

    • x86... 明智吗?这是一个新的
    【解决方案4】:

    “随便读集”lol(很好)

    我会在运行时跟随 gdb 开始;你对正在发生的事情有更好的感觉。但也许那只是我。它会为你反汇编一个函数(disass func)然后你可以单步执行它

    如果您这样做只是为了检查优化 - 不用担心。

    a) 编译器做得很好

    b) 你无论如何都无法理解它在做什么(没人能)

    【讨论】:

    • 有时我发现优化后的代码更易于阅读,因为它会注意到冗余的地方并将其更改为我会写的内容。
    • 就我自己而言,我知道这样做只是为了检查优化是个好主意。原因是每次看到编译器真的对situation X做了一些聪明的事情,我以后都不会再花时间wondering了。 avpx 也有很好的一点。
    • +1,这是个好主意,我已将 disass func 添加到 gdb 上的 CW:stackoverflow.com/questions/2588853/…。无论如何,请随意编辑我放在那里的内容。
    【解决方案5】:

    与高级语言不同,能够阅读汇编和能够编写汇编之间并没有太大(如果有的话)区别。指令与 CPU 操作码具有一对一的关系——没有复杂性可以跳过,同时仍保持对代码行功能的理解。 (它不像高级语言,你可以看到一行写着“print $var”,而不需要知道或关心它是如何将它输出到屏幕上的。)

    如果您仍想学习汇编,请阅读 Jeff Duntemann 的书 Assembly Language Step-by-Step: Programming with Linux

    【讨论】:

    • 我不同意(但不会因此而投反对票);理解已知格式正确的内容并自己创建格式正确的代码要容易得多。能够阅读程序集当然可以帮助/编辑/程序集,但是能够阅读它与能够从头开始编写甚至是微不足道的功能相去甚远。当人们用我学过的外语与我交谈时,我或许能听懂,但我肯定不能以正确的方式说他们中的任何一种!
    【解决方案6】:

    我确信那里有介绍性书籍和网站,但学习它的一种非常有效的方法实际上是获取英特尔参考资料,然后尝试用你喜欢的方式做一些简单的事情(如整数数学和布尔逻辑)高级语言,然后看看生成的二进制代码是什么。

    【讨论】:

    • GCC 使用 AT&T 语法作为输出有点复杂。 MOV 不只是称为MOV,而且操作数的顺序并不总是英特尔手册中列出的顺序。
    • 如果您正在为 x86 编译,您可以使用编译器标志 -masm=intel 让 gcc 输出看起来更像英特尔手册的程序集。
    猜你喜欢
    • 1970-01-01
    • 2011-08-25
    • 2014-07-10
    • 2023-04-03
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    相关资源
    最近更新 更多