【问题标题】:is there any use for GCC -S flag with gcc -cGCC -S 标志和 gcc -c 有什么用吗
【发布时间】:2020-02-27 14:18:55
【问题描述】:

我想知道在我的 Makefile 中使用 -S GCC 选项是否有任何好处。

我已经编译如下 C 文件已经有一段时间了:

gcc -c a.c -o a.o
gcc -c b.c -o b.o
---
gcc a.o b.o -o a.out

现在会更好:

gcc -S a.c -o a.s
gcc -S b.c -o b.s
---
gcc -c a.s -o a.o
gcc -c b.s -o b.o
---
gcc a.o b.o -o a.out

显然还有跳过.o 阶段的选项,直接将.s 文件组装成二进制文件。您认为哪个选项最好,为什么?

【问题讨论】:

  • 为什么要将汇编代码作为中间阶段?在大多数情况下,人们并不关心实际的汇编代码。
  • 出于某种原因您要检查生成的汇编代码吗?
  • 不是真的,我想那没有意义
  • 您也可以通过调用gcc a.c b.c -o a.out 完全跳过.s.o。中间对象文件很有用,例如,如果您的构建过程不止一次需要它们。

标签: c gcc makefile


【解决方案1】:

-S flags 要求 gcc 生成人类可读的汇编代码 - .o 文件对于链接器来说很好,但对于大多数人来说却很神秘......

它主要用于当您需要对通过分析识别为瓶颈的(短)代码段进行低级优化时。您可以比较编译器将如何翻译各种版本,并选择能够为特定实现提供最高效机器代码的版本

它不适用于标准 makefile。

【讨论】:

    【解决方案2】:

    显然还有跳过.o 阶段的选项,直接将.s 文件组装成二进制文件。

    普通程序集永远不会直接转换为可执行的二进制代码,始终存在中间目标文件步骤。

    gcc a.s b.s -o ab.exe
    

    总是会调用汇编器(两次),它为任一单元生成目标代码,然后链接对象。在命令行中添加-v,查看gcc执行了哪些子命令。 gcc 实际上不是编译器,它只是一个驱动程序根据选项和文件扩展名调用作业。正确的编译器是 cc1(用于 C 代码)、cc1plus(用于 C++ 代码)等。

    您认为哪个选项最好,为什么?

    -S 具有生成汇编代码的优势,但是编译器将总是生成汇编代码作为中间步骤。只是它被写入临时文件的情况,有两个明显的例外:

    • -save-temps:这不会使用一些临时文件名(例如/tmp),而是将中间代码保存在与对象相同的位置(实际上有两种风格,-save-temps=obj-save-temps=src)。

    • -pipe:这将使用管道将代码从一个 sup-program 传输到下一个而不是文件(-save-temps 除外,它会使 -pipe 无效)。

    因此,如果您想查看生成的程序集,-save-temps 可能是要走的路。但是,该选项也适用于保存在 C 的 .i、C++ 的 .ii 和汇编的 .s 中的预处理代码。在使用 C 宏时,这通常是非常受欢迎的。

    如果您打算检查编译器生成的程序集,您可能会喜欢-fverbose-asm,它会注入指示与程序集关联的 C/C++ 源代码的 asm cmets。在这种情况下,最好不要用调试信息来混淆程序集。

    【讨论】:

      猜你喜欢
      • 2011-03-23
      • 1970-01-01
      • 2023-03-10
      • 2011-08-16
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      相关资源
      最近更新 更多