如何编译GCC生成的asm?

问题描述:

我正在玩一些asm代码,并且有些东西在困扰着我。如何编译GCC生成的asm?

我编译如下:

#include <stdio.h> 

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

gcc file.c -S -o file.S这会产生一个漂亮的小片的汇编代码:

.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为我做?

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

gcc -c file.S -o file.o 

这会给出名为file.o的目标代码文件。 要调用链接器上面的命令之后执行以下:

gcc file.o -o file 
+9

你也可以使用'gcc file.S -o file' –

+0

“> as -o hello.o hello.s”?如https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html所示。似乎进程的顺序是预处理(* .i-file),编译(* .s-file),汇编(* .o-file)和链接(* .exe-file)。 – user1677716

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

+1

如何找出如何GCC会使用的一些binutils的? –

+0

另外,我有英特尔icc躺在周围,他们使用什么汇编程序? –

+4

@Martin,请'gcc -v'来叙述它的行为。 –

您可以使用天然气,这是gcc的后端汇编:

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

可以在一个普通的C程序中嵌入的汇编代码。这是一个很好的introduction。使用适当的语法,你也可以告诉GCC要在C.声明的变量相互作用下程序指示GCC是:

  • EAX应富
  • 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; 
} 

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

  • 如果文件名以“.s”(小写字母“S”),然后gcc调用汇编结束。
  • 如果文件名称结尾“.S”(大写的“S”),然后gcc适用于源文件C预处理程序(即它识别指令,如#if,并取代宏),并然后上调用汇编结果。

所以,一般的基础上,你想要做这样的事情:

gcc -S file.c -o file.s 
gcc -c file.s 
+0

这看起来像它的工作,但我得到一个错误消息:'格式错误的Mach-o文件' –

+0

我认为你必须使用'.S'前缀(大写),否则gcc检测另一个文件类型(例如'.asm'失败) –

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

这是一个很简短的答案。你能补充一些解释吗?也许你可以告诉我们参数与其他答案的区别。 – GameDroids

如果你有main.s文件。 您可以通过GCC生成目标文件,也as

# gcc -c main.s 
# as main.s -o main.o 

检查这个环节,它会帮助你学习GCC http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/