Edited at
移行Day 2

AdventCalendar Day02 [超Ruby入門]


はじめに

本記事は、超Ruby入門2日目の記事です。

コメント頂ける方は、ガイドラインを読んで頂けると幸いです。


目的

ある現象がどのようにして、起こるのかを調べる姿勢を身につける


目標

Hello Worldが出力されるまでにGCCが何を行っているかを確認する。


事前知識

$gcc hello.c

を実行すると、a.outという実行ファイルが生成される。

GCCは、a.outが生成されるまでに4つの処理が行う。


  • 前処理(プリプロセッサ)

  • コンパイル

  • アセンブル

  • リンク


前処理

前処理は、ヘッダーファイルの読み込み(ex. stdio.h)やコメントの削除などを行う。


コンパイル

コンパイルは、ソースコードからアセンブリ言語で書かれたプログラムを生成する。


アセンブル

アセンブルは、コンパイルで生成したアセンブラプログラムからオブジェクトプログラムを生成する。


リンク

リンクは、オブジェクトプログラムを一つにまとめて実行ファイルを生成する。


本題

#include <stdio.h>

int main(){
printf("Hello World\n");
return 0;
}


前処理

Hello Worldと出力されるコードを前処理してみよう。

$gcc -E hello.c

標準出力に前処理の結果が見えるはずだ。

ヘッダーファイルが読み込まれているのかを確認するために、#include <stdio.h>をコメントアウトして再度、前処理をかけてみよう。

すると今度は、以下のような出力結果になるはずだ。これで、前処理の行っていることがわかった。

# 1 "hello.c"

# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 361 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "hello.c" 2

int main(){
printf("Hello World\n");
return 0;
}


コンパイル

次に、コンパイルをしてみよう。すると、hello.sというアセンブラプログラムが生成される。

$gcc -S hello.c


アセンブル

hello.sをアセンブルしよう。hello.oというオブジェクトファイルができる。

catコマンドなどで覗くと人間には、わからないものが生成されているはずだ。

$as -o hello.o hello.s

または、
$gcc -c hello.c


リンク

hello.oをリンクしよう。リンクして生成された実行ファイルを実行するとHello Worldの出力されているはずだ。

$gcc -o hello hello.o

$./helllo


まとめ

これで、GCCで何を行っているのか知ることができた。

各処理を詳しく掘り下げたり、stdio.hの中身を覗いて見ると面白いかもしれない。

明日は、丸ばつゲームを開発する。


深めたい方

モノづくりが大好き! のホームページ


参考文献

プリプロセッサ

コンパイルのしくみ