如何编译GCC生成的asm?

时间:2011-08-25 12:07:38

标签: c gcc compiler-construction assembly

我正在玩一些asm代码,有些事情困扰着我。

我编译了这个:

#include <stdio.h>

int main(int argc, char** argv){
  printf("Hello World\n");
  return 0;
}

使用gcc file.c -S -o file.S这会生成一小段asm代码:

    .cstring
LC0:
    .ascii "Hello World\0"
    .text
.globl _main
_main:
LFB3:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    subq    $16, %rsp
LCFI2:
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    leaq    LC0(%rip), %rdi
    call    _puts
    movl    $0, %eax
    leave
    ret
LFE3:
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
    .set L$set$0,LECIE1-LSCIE1
    .long L$set$0
LSCIE1:
    .long   0x0
    .byte   0x1
    .ascii "zR\0"
    .byte   0x1
    .byte   0x78
    .byte   0x10
    .byte   0x1
    .byte   0x10
    .byte   0xc
    .byte   0x7
    .byte   0x8
    .byte   0x90
    .byte   0x1
    .align 3
LECIE1:
.globl _main.eh
_main.eh:
LSFDE1:
    .set L$set$1,LEFDE1-LASFDE1
    .long L$set$1
LASFDE1:
    .long   LASFDE1-EH_frame1
    .quad   LFB3-.
    .set L$set$2,LFE3-LFB3
    .quad L$set$2
    .byte   0x0
    .byte   0x4
    .set L$set$3,LCFI0-LFB3
    .long L$set$3
    .byte   0xe
    .byte   0x10
    .byte   0x86
    .byte   0x2
    .byte   0x4
    .set L$set$4,LCFI1-LCFI0
    .long L$set$4
    .byte   0xd
    .byte   0x6
    .align 3
LEFDE1:
    .subsections_via_symbols

我的下一个问题是,如何编译此输出,我可以让GCC为我做这个吗?

7 个答案:

答案 0 :(得分:76)

是的,您可以使用gcc编译您的asm代码。使用-c进行编译,如下所示:

gcc -c file.S -o file.o

这将给出名为file.o的目标代码文件。 要调用链接器,请执行以下命令:

gcc file.o -o file

答案 1 :(得分:45)

gcc可以使用程序集文件作为输入,并根据需要调用汇编程序。但是有一个微妙之处:

  • 如果文件名以“.s”(小写的's')结尾,则gcc会调用汇编程序。
  • 如果文件名以“.S”结尾(大写“S”),则gcc在源文件上应用C预处理器(即它识别#ifgcc -S file.c -o file.s gcc -c file.s 等指令。替换宏),然后在结果上调用汇编程序。

所以,总的来说,你想做这样的事情:

{{1}}

答案 2 :(得分:10)

您可以将汇编代码嵌入到普通的C程序中。这是一个很好的introduction。使用适当的语法,您还可以告诉GCC您想要与C中声明的变量进行交互。下面的程序指示gcc:

  • eax应该是foo
  • ebx应该是吧
  • 执行汇编代码后,eax中的值应存储在foo中

\ n

int main(void)
{
        int foo = 10, bar = 15;
        __asm__ __volatile__("addl  %%ebx,%%eax"
                             :"=a"(foo)
                             :"a"(foo), "b"(bar)
                             );
        printf("foo+bar=%d\n", foo);
        return 0;
}

答案 3 :(得分:3)

是的,gcc还可以编译汇编源代码。或者,您可以调用as,这是汇编程序。 (gcc只是一个“驱动程序”程序,它使用启发式方法来调用C编译器,C ++编译器,汇编器,链接器等。)

答案 4 :(得分:3)

您可以使用GAS,它是gcc的后端汇编程序:

http://linux.die.net/man/1/as

答案 5 :(得分:2)

如果你有main.s文件。 您可以按GCCas

生成目标文件
# gcc -c main.s
# as main.s -o main.o

检查此链接,它将帮助您了解GCC的一些binutils http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/

答案 6 :(得分:0)

nasm -f bin -o 2_hello 2_hello.asm