【问题标题】:Compile beyond pre-processor stage but before assembly stage编译超出预处理器阶段但在汇编阶段之前
【发布时间】:2012-03-05 11:30:13
【问题描述】:

假设我在一个程序 (macrotest.c) 中有一组宏,如下所示:

#include <stdio.h>
#include <stdlib.h>
#define n1 75
#define n2 90
#define mac(x,y) ((x > y) ? (12) : (15))

int main(){

   printf("%d",mac(n1,n2));
   exit(0);
}

当您编译成汇编 (EM64T) 时,您会得到以下结果:

gcc -S -o macrotest.asm macrotest.c

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %eax
    movl    $15, %esi   <------ This
    movq    %rax, %rdi
    movl    $0, %eax
    call    printf
    movl    $0, %edi
    call    exit
    .cfi_endproc

您可以看到它立即将 mac(n1,n2) 转换为 15。 但是,当您编译到预处理器阶段时,它只是扩展了宏:

gcc -E -o macrotest.prp macrotest.c

int main(){

   printf("%d",((75 > 90) ? (12) : (15)));
   exit(0);
}

有没有什么方法可以进一步分解 C 代码而不进入汇编程序?

【问题讨论】:

  • 我认为你不能比这更深入,因为在编译时应用了优化,因此 15 来自首先解析表达式,然后进行就地评估。
  • @JesusRamos 当然有一些工具可以满足我的要求。
  • 好吧,编译器会这样做,但问题是它不会真正产生这样的输出(在你的情况下,只需用 15 替换整个东西),因为其中一些是特定的并且需要代码重新排序可能会使代码几乎不可读。
  • @JesusRamos 你可能是对的。我还是会在这个问题上坐一会儿,这很重要。
  • 我见过从汇编到 TCG 再返回的实用程序,但从来没有直接在代码中进行内联优化的工具。如果确实存在这样的工具会很有趣。

标签: c gcc compilation macros c-preprocessor


【解决方案1】:

试试-fdump-tree-all 选项,看看它是否能告诉您您需要什么?

这会转储编译器的内部表示。它不使用 C 代码(您无法获取并编译它),但它看起来确实有点像 C。如果您想进一步了解它,请阅读“单一静态分配”(SSA)。

如果您想进一步了解汇编程序,请添加-fdump-rtl-all。在进程的后半部分,GCC 从 SSA 形式(编译器尝试优化程序)切换,并使用它所谓的“注册传输语言”。此阶段的目的是优化低级机器指令的使用。这更难理解。尝试阅读 GCC 内部手册。

【讨论】:

    猜你喜欢
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多