逆アセンブルで遊んでみる(0)何もしない関数

「フィーリングで読むアセンブラ入門」の発売が待ち遠しくて、いかにも発狂しそうですが、発売日まで、自分の環境で逆アセンブルして我慢しようということで…。

今回のソースコードは、こんな内容。内部で何も行わない関数の逆アセンブルを行ってみます。

/* asm000.c */
void func(void)
{
}

上のソースファイルに対して、以下のコマンドを実行して、オブジェクトファイルを生成します(-Wallで「すべての警告を表示」、-O0で「最適化を行わない」、-cで「アセンブルまで行い、オブジェクトファイルを生成する(リンクは行わない)」)。リンクは行わないので、main関数が存在しなくても大丈夫です。

$ gcc -Wall -O0 -c asm000.c 

オブジェクトファイルについて、GNU binutilsの「objdump」を実行すると(以下コマンド)、逆アセンブルの結果が出力されます。

$ objdump -d asm000.o

アセンブルの結果は以下。

   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	5d                   	pop    %ebp
   4:	c3                   	ret   

これは、関数呼出し時の定石なので、眺めておくにとどめます。何をやっているかというと…

1.現在のベースポインタをスタックに退避。
2.現在のスタックポインタで、スタックフレームの設定。
3.1で退避したベースポインタをスタックポインタに設定。
4.ret命令で、呼出し元に戻る。

関数呼出し前のベースポインタの内容を退避しておいて、呼出し元に戻る際に、ベースポインタの内容を原状回復する…ってことをやってます。今回は関数内で何も処理していないですが、何か処理がなされる場合は、2と3の間で行います。

だから何だ!