为什么 GCC 不能编译 CLANG 生成的程序集?

Why can't GCC compile assembly produced by CLANG?

所以,我注意到 CLANG 生成的程序集无法用 GCC 编译。例如,对于一个简单的 "Hello world!" C 程序,CLANG 生成以下程序集:

    .text
    .file   "hello.c"
    .globl  main                    # -- Begin function main
    .p2align    4, 0x90
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    , %rsp
    movabsq $.L.str, %rdi
    movb    [=10=], %al
    callq   printf
    xorl    %ecx, %ecx
    movl    %eax, -4(%rbp)          # 4-byte Spill
    movl    %ecx, %eax
    addq    , %rsp
    popq    %rbp
    .cfi_def_cfa %rsp, 8
    retq
.Lfunc_end0:
    .size   main, .Lfunc_end0-main
    .cfi_endproc
                                        # -- End function
    .type   .L.str,@object          # @.str
    .section    .rodata.str1.1,"aMS",@progbits,1
.L.str:
    .asciz  "Hello world!\n"
    .size   .L.str, 14

    .ident  "clang version 10.0.0 "
    .section    ".note.GNU-stack","",@progbits
    .addrsig
    .addrsig_sym printf

但是,当我尝试使用 gcc hello.s 编译该程序集时,我得到:

hello.s: Assembler messages:
hello.s:37: Error: unknown pseudo-op: `.addrsig'
hello.s:38: Error: unknown pseudo-op: `.addrsig_sym'

但是 GCC 和 CLANG 使用相同的汇编程序,即 GNU 汇编程序。那么,这里到底发生了什么?

这是什么目标?我从 movabsq $.L.str, %rdi 猜测 MacOS - 针对 Linux 编译器将使用 mov $.L.str, %edi 作为位置-dependent(非 PIE)代码(否则是相对于 RIP 的 LEA),并且 Windows 具有不同的调用约定。 clang 在这里没有使用相对于 RIP 的 LEA,这实际上是非常令人惊讶的;它会小于 movabs.

据推测,.addrsig 指令是特定于 clang 的,对于 GAS 不知道如何创建的 MachO64 元数据。这可能也是 Apple 版本的 Clang,而不是主线 clang。

But both GCC and CLANG use the same assembler, the GNU Assembler.

不,它们使用相同的 asm 语法,但 clang 有一个集成的汇编器。正如@Marc Glisse 指出的那样,您可以使用 clang -no-integrated-as 来禁用它,这会将其提供给 GAS 并且可能会失败。