2011-08-25 149 views
48

我正在玩一些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爲我做?

回答

61

是的,你可以使用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

3

是的,gcc也可以編譯彙編源代碼。或者,您可以調用匯編程序as。 (GCC只是一個「驅動程序」的程序,採用啓發式方法來調用C編譯器,C++編譯器,彙編器,連接器等。)

+1

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

+0

另外,我有英特爾icc躺在周圍,他們使用什麼彙編程序? –

+4

@Martin,請'gcc -v'來敘述它的行爲。 –

7

可以在一個普通的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; 
} 
37

後可以使用匯編文件作爲輸入,並根據需要調用匯編程序。有一個細微之處,但:

  • 如果文件名以「.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'失敗) –

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

這是一個很簡短的答案。你能補充一些解釋嗎?也許你可以告訴我們參數與其他答案的區別。 – GameDroids