gccはプリプロセス、コンパイル、アセンブル、リンク

gccコンパイルするツールという認識しかなかったけど、プリプロセス、コンパイルアセンブル、リンクという4つの処理をまとめて行ってくれていたらしい。

以下のコマンドで1つずつ処理を進められるので、中間ファイルを確認できる。

プリプロセス:gcc -E

 => #includeや#defineなどの文を展開する

コンパイルgcc -S

 => C言語のソースをアセンブリ言語のソースに変換する

アセンブルgcc -c

 => アセンブリ言語のソースを機械語のオブジェクトに変換する

リンク:gcc

 => オブジェクトをリンクして実行形式にする

 

-E, -S, -cはそれぞれ何の略かわからないけど、エスケープ(ESc)の順番だと思えば覚えられるかもしれない。。。

 

[shin@cent6-5 helloworld]$ gcc -E helloworld.c > helloworld.i
[shin@cent6-5 helloworld]$ gcc -S helloworld.i 
[shin@cent6-5 helloworld]$ ll
合計 28
-rw-rw-r--. 1 shin shin    61 11月  8 01:01 2014 helloworld.c
-rw-rw-r--. 1 shin shin 16736 11月 16 20:47 2014 helloworld.i
-rw-rw-r--. 1 shin shin   467 11月 16 20:57 2014 helloworld.s
[shin@cent6-5 helloworld]$ cat helloworld.s 
	.file	"helloworld.c"
	.section	.rodata
.LC0:
	.string	"hello world!"
	.text
.globl main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$.LC0, %eax
	movq	%rax, %rdi
	movl	$0, %eax
	call	printf
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
	.section	.note.GNU-stack,"",@progbits
[shin@cent6-5 helloworld]$ gcc -c helloworld.s 
[shin@cent6-5 helloworld]$ ll
合計 32
-rw-rw-r--. 1 shin shin    61 11月  8 01:01 2014 helloworld.c
-rw-rw-r--. 1 shin shin 16736 11月 16 20:47 2014 helloworld.i
-rw-rw-r--. 1 shin shin  1512 11月 16 20:58 2014 helloworld.o
-rw-rw-r--. 1 shin shin   467 11月 16 20:57 2014 helloworld.s
[shin@cent6-5 helloworld]$ gcc -o helloworld helloworld.o
[shin@cent6-5 helloworld]$ ll
合計 40
-rwxrwxr-x. 1 shin shin  6432 11月 16 20:59 2014 helloworld
-rw-rw-r--. 1 shin shin    61 11月  8 01:01 2014 helloworld.c
-rw-rw-r--. 1 shin shin 16736 11月 16 20:47 2014 helloworld.i
-rw-rw-r--. 1 shin shin  1512 11月 16 20:58 2014 helloworld.o
-rw-rw-r--. 1 shin shin   467 11月 16 20:57 2014 helloworld.s
[shin@cent6-5 helloworld]$ ./helloworld 
hello world!