私はいくつかの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にそれをさせることができますか?
はい、gccを使用してasmコードをコンパイルできます。次のようにコンパイルするには-cを使用します。
gcc -c file.S -o file.o
これにより、file.oという名前のオブジェクトコードファイルが作成されます。リンカを呼び出すには、上記のコマンドの後に次を実行します。
gcc file.o -o file
gcc
は、アセンブリファイルを入力として使用し、必要に応じてアセンブラを呼び出すことができます。ただし、微妙な点があります:
.s
」(小文字の 's')で終わる場合、gcc
はアセンブラーを呼び出します。.S
」(大文字の「S」)で終わる場合、gcc
はソースファイルにCプリプロセッサを適用します(つまり、#if
などのディレクティブを認識し、マクロを置き換えます) 、およびthenは、結果に対してアセンブラーを呼び出します。そのため、一般的には、次のようなことをしたいと思います。
gcc -S file.c -o file.s
gcc -c file.s
通常のCプログラムにアセンブリコードを埋め込むことができます。良い 紹介 です。適切な構文を使用して、Cで宣言された変数と対話することをGCCに伝えることもできます。以下のプログラムは、gccに次のことを指示します。
\ 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;
}
はい、gccはアセンブリソースコードもコンパイルできます。または、アセンブラーであるas
を呼び出すこともできます。 (gccは、ヒューリスティックを使用してCコンパイラ、C++コンパイラ、アセンブラ、リンカなどを呼び出す単なる「ドライバ」プログラムです。)
GCCのバックエンドアセンブラーであるGASを使用できます。
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/
nasm -f bin -o 2_hello 2_hello.asm