web-dev-qa-db-ja.com

GCCによって生成されたasmをコンパイルするにはどうすればよいですか?

私はいくつかの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にそれをさせることができますか?

65

はい、gccを使用してasmコードをコンパイルできます。次のようにコンパイルするには-cを使用します。

gcc -c file.S -o file.o

これにより、file.oという名前のオブジェクトコードファイルが作成されます。リンカを呼び出すには、上記のコマンドの後に次を実行します。

gcc file.o -o file
78
cyber_raj

gccは、アセンブリファイルを入力として使用し、必要に応じてアセンブラを呼び出すことができます。ただし、微妙な点があります:

  • ファイル名が「.s」(小文字の 's')で終わる場合、gccはアセンブラーを呼び出します。
  • ファイル名が「.S」(大文字の「S」)で終わる場合、gccはソースファイルにCプリプロセッサを適用します(つまり、#ifなどのディレクティブを認識し、マクロを置き換えます) 、およびthenは、結果に対してアセンブラーを呼び出します。

そのため、一般的には、次のようなことをしたいと思います。

gcc -S file.c -o file.s
gcc -c file.s
45
Thomas Pornin

通常のCプログラムにアセンブリコードを埋め込むことができます。良い 紹介 です。適切な構文を使用して、Cで宣言された変数と対話することをGCCに伝えることもできます。以下のプログラムは、gccに次のことを指示します。

  • eaxはfooとする
  • ebxはbar
  • 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;
}
10

はい、gccはアセンブリソースコードもコンパイルできます。または、アセンブラーであるasを呼び出すこともできます。 (gccは、ヒューリスティックを使用してCコンパイラ、C++コンパイラ、アセンブラ、リンカなどを呼び出す単なる「ドライバ」プログラムです。)

4
zvrba

GCCのバックエンドアセンブラーであるGASを使用できます。

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

3
Brian Gordon

Main.sファイルがある場合。 GCCおよびasによってオブジェクトファイルを生成できます

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

このリンクを確認してください。GCCのbinutilsを学ぶのに役立ちます http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/

2
Srinivas Achary
nasm -f bin -o 2_hello 2_hello.asm
0
Hassan Maher