連載
» 2017年05月18日 05時00分 UPDATE

main()関数の前には何があるのか(1):「Hello World!」の中身を探る意義と環境構築、main(C言語)のアセンブラコードの読み方 (2/4)

[坂井弘亮,著]

ハロー・ワールドに触れてみる

 まずは、本書で扱うサンプル・プログラムについて説明したい。サンプル・プログラムのソースコードとコンパイル方法、実行時の出力などを簡単になぞっておこうと思う。

 また本書ではLinuxのカーネル・ソースコードなど、様々なソフトウェアのソースコードを参照する。

 さらにハロー・ワールドに対して、様々な解析を行う。

 具体的にはデバッガを用いた動的解析や、実行ファイルの静的解析などを行う。ライブラリのソースコードを参照したり、実行ファイルをバイナリファイルとして直接扱うようなこともある。

 そしてこれらの解析のためには、解析用の様々なツール類も必要になる。本書ではそうしたツール利用の環境を気軽に利用できるようにするために、VM(Virtual Machine)によるCentOS 環境のイメージを用意している。

 本章では準備として、サンプル・プログラムと参照用の各種ソースコード、さらにVMによるCentOS環境について説明しよう。

ハロー・ワールドのサンプル・プログラム

 まずは本書で扱うハロー・ワールドのサンプル・プログラムを説明しよう。リスト1.1がハロー・ワールドのサンプルだ。ファイル名はhello.cとする。

#include <stdio.h>
 
int main(int argc, char *argv[])
{
  printf("Hello World! %d %s\n", argc, argv[0]);
  return 0;
}
リスト1.1: ハロー・ワールド(hello.c)

 本書で主に扱うプログラムは、これだけだ。ただの数行のプログラムなので、覚えることは難しくはないだろう。

 なおリスト1.1ではmain()関数の引数としてargcとargvをとり、それをprintf()に渡して出力している。

 一般的なハロー・ワールドはそこまでしていないかもしれないが、これは本書では引数の処理等を見たいためにそのようにしている。まあひとまずはそのようなものとして、気にしなくても構わない。

 ここで気にしなければならないのは、以下のようなことだ。

  • printf()という関数を呼んでいるが、呼び出し先ではどのようなことが行われているのだろうか?
  • main()という関数があるが、これはどこから呼ばれて、どこに戻るのだろうか?
  • stdio.hというファイルをインクルードしているが、これはいったいどこにある、どのようなファイルなのだろうか?

 こうした「素朴な疑問」をとことん探っていくのが、本書の目的になる。

サンプル・プログラムのダウンロードについて

 サンプル・プログラムのソースコードや生成済みの実行ファイルなどは、書籍のサポートページからhello.zipというファイルとしてダウンロードできる。

http://kozos.jp/books/helloworld/
hello.zip

 本書で扱う実行ファイルはリスト1.1のサンプル・プログラムを後述のCentOS6の環境でコンパイルし生成したものだ。

 同等の環境を用意して実行ファイルを新たに生成することは可能だが、実行ファイルを生成しなおした場合、たとえ環境を合わせたとしても、生成される実行ファイルは微妙に異なるものになる可能性がある。ツールやライブラリのバージョンの違いなどが影響する可能性があるためだ。

 このため本文中で行っている操作を正確になぞりたいようなときには、自身の環境で生成した実行ファイルではなく、上記サイトのコンパイル済みの実行ファイルを利用してほしい。

 なおhello.zipを解凍する際には、以下のディレクトリ上に展開するようにしてほしい。これはGDBによるデバッグ時にソースコードが参照されるため、ソースコードを実行ファイルの生成時のディレクトリに合わせて配置しておいたほうが問題が起きにくいからだ。

/home/user

 hello.zipを展開すると12 個のファイルがあり、それぞれ表1.1のような意味を持っている。実行ファイルについては、様々な条件でコンパイルしたものを用意している。

表1.1: ファイルの一覧
ファイル名 ファイル種別 概要
Makefile Makefile 実行ファイルの生成用
hello.c Cソースコード サンプル・プログラムのソースコード
hello 実行ファイル 静的リンクしたもの(主にこれを解析する)
hello-normal 実行ファイル 共有ライブラリを使った、通常のコンパイル
hello-opt 実行ファイル -O1で最適化
hello-opt2 実行ファイル -O2で最適化
hello-opts 実行ファイル -Osで最適化
hello-nfp 実行ファイル フレームポインタを利用しない
hello-ndbg 実行ファイル デバッグオプションを無効化
hello-strip 実行ファイル stripによるサイズ削減
simple.c Cソースコード さらにシンプルなハロー・ワールド
simple 実行ファイル sample.cのコンパイル済み実行ファイル

各種ソースコードの入手について

 本書では以下のソフトウェアのソースコードを参照している。

  • Linuxカーネル
  • GNU C Library(glibc)
  • FreeBSD
  • GNU Debugger(GDB)
  • Newlib

 これらのソースコードはそれぞれの本家の配布サイトからも取得できるが、上述した本書のサポートサイトにも置いてある。またサポートサイトには、本家サイトへのリンクも張ってある。

VMによるCentOS環境の利用について

 本書の内容はCentOS 6の32ビット版の環境で確認してある。

 よってPC上にCentOSをインストールすれば、本書の内容を確認することは可能だ。また、もちろんUbuntuなどの他のGNU/LinuxディストリビューションやCygwin、FreeBSDなどの環境でも本書の手順に従った操作はできるかとは思う。

 しかしツール類のバージョンなどがそろわない場合、細かい手順や結果等が微妙に異なる可能性がある。

 実際に確認を行った環境は以下のVMイメージにしてあり、本書のサポートサイトからダウンロードできるようにしてある。

helloworld-CentOS6.ova

 よって、やはり本書の内容を正確になぞりたいようなときには、上記のVMイメージを利用するのがいいだろう。解析だけならばそれほどの違いは無いかもしれないが、実行ファイルを生成する場合には、環境によって大きな差異が発生する。

なお上記VMイメージを利用する場合、yum updateするかどうかは悩ましい問題だ。ライブラリ類が更新されると実行ファイル生成時のアドレス配置などが変わってくる可能性は十分にある。インターネットに接続しない環境でセキュリティ的な安全性が確保されるならば、yum updateをしないで使うことも考えられる。このあたりは自己責任で判断してほしい。


Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。