関数呼び出し
(C言語の)関数の呼び出し方に関するコンベンション類。原典がどこにあるか良く分からないので、ソースは日本語だったり観察から得られた事実だったりします。
環境は、gas 2.17.50 gcc 4.1.2 x86(Pentium M) Ubuntu Feisty Fawn ってな感じです。
関数に入るときと出るときとで変化してはいけないレジスタ: EBP, ESP, EDI, ESI, EBX
戻り値を格納するレジスタ: EAX
関数呼び出し側では引数をスタックにプッシュしてcallするだけ。
呼び出された関数では EBP をスタック上に保存し、 ESP は関数を抜けるときに復元する。
EDI・ESI・EBXは(必要に応じて)スタック上に保存しておき、戻る前に元通りにする。
この辺はマクロ化しても良いくらいの常套句になってるぽ。
ただし、EDIやESIを使わない場合はわざわざ保存しないことも多々あるらしい。
func: pushl %ebp movl %esp, %ebp pushl %edi pushl %esi pushl %ebx # ここに処理が入るなんです♪ popl %ebx popl %esi popl %edi popl %ebp ret
main関数では、次の数命令が定型文になっている模様。
main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx # ここに関数本体が入るなんです♪ popl %ecx popl %ebp leal -4(%ecx), %esp ret
一文字ぶん字下げしたところは通常の関数と同じことをしている部分。それらに挟まれて、ECXの値をpushしてる。これはプログラムの最後にECXからESPを復元したいがため。
andl $-16, %esp は、ESPの値の下四桁をオフしているってことですね。オフするってことはESPは減少する、つまりスタックが伸びる方向へ移動する。
leal 4(%esp), %ecx と、ECXをスタックの伸びる方向とは逆の位置に指定しているのは、andl $-16, %esp したあとのESPの位置が変わらなかった場合に備えているのだと思う。・・・たぶん。(あれ、でも、考えてみるとこれだけの命令だったらなんも効果が無いな・・・)
で、mainが終わったあとにはECXやEBPを復元したあと、そのECXからESPの値を元通り復元すれば出来上がり。ってなもんだ。
__attribute__((constructor))と__attribute__((destructor))で定義された関数については、
.globl premain .type premain, @function premain: pushl %ebp movl %esp, %ebp # ここに処理が入るなんです♪ popl %ebp ret .size premain, .-premain .section .ctors,"aw",@progbits .align 4 .long premain .text .globl postmain .type postmain, @function postmain: pushl %ebp movl %esp, %ebp # ここに処理が入るなんです♪ popl %ebp ret .size postmain, .-postmain .section .dtors,"aw",@progbits .align 4 .long postmain .section .rodata
ごく普通の関数と同じであって、「main関数を呼び出す、ひとつながりの関数」ということは無い。単に、main関数の前とあとに呼ばれるだけの関数。
じゃあやっぱり、(プロセスごとに仮想メモリ空間が使用される今となっては)main関数の前後で各レジスタの値をストアしておく必要って特にない気がする。
あと、グローバル変数はシンボルでアクセスしてた。たぶんロード時に具体的な数値と入れ替えるんじゃないかと思う。ロード時の動作とかその読み方についてはまだ全然分かんないけど。
※リンク時にやるっぽい。
今日の参考ページ:
http://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA%E8%A6%8F%E7%B4%84
http://lily.fan.gr.jp/~kmd/adhoc/memo/sutakku.txt
http://practical-scheme.net/docs/stack-j.html
http://labs.cybozu.co.jp/blog/takesako/2007/05/fizzbuzz_x86.html
http://hp.vector.co.jp/authors/VA014520/asmhsp/chap4.html
http://d.hatena.ne.jp/Yamami/20041208
http://homepage1.nifty.com/herumi/prog/prog11.html
http://www.sol.dti.ne.jp/~yoshinor/program/prog0002.html
あと、http://www.sandpile.org/ia32/index.htmここは何やら面白い。説明こそ無いけれど、様々な仕様について書かれていて、場合によってはとても便利。