逆アセンブルで遊んでみる(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の間で行います。
だから何だ!