呼び出し規約
x86
EAX, ECX, EDX は破壊して良し。逆に言うと EBX, EDI, ESI は保存すること。
引数はスタックで後ろから順に。
浮動小数返す時は FPU のスタックトップを使う。渡す時は普通にスタック上で。
linux のシステムコールは EAX, EBX, ECX, EDX に突っ込む。 int 0x80 か sysenter で入る。
x86_64
RAX, RCX, RDX, RSI, RDI, R8-11 は破壊可。 RBX, R12-15 は callee で保存。 SSE レジスタは破壊していい。
引数は RDI, RSI, RDX, RCX, R8, R9 で残りはスタック。
RDI と RSI が破壊可になってるんだなぁという。
浮動小数は SSE レジスタでやりとり。 xmm0 で返して、引数は後ろから順に xmm0, 1, ...
linux のシステムコールも似た呼び出し規約っぽい。 RAX にシステムコール番号をつっこんで、引数は関数呼び出しと同じ。呼び出す時は int 0x80 じゃなくて syscall を使う。なんかシステムコール番号は 32bit と 64bit で違うので注意。
あと int 0x80 で呼ぶと 32bit のルールに従うぽい。 sysenter はなんか SEGV するんだが。
あと重要なのは AX や AL と違って、 EAX に書き込むと RAX の上位がクリアできるってことかな。おかげで命令長短くなったり。
参考になった: http://www.milw0rm.com/papers/110
大きなオブジェクトとかは…まぁとりあえずいいや。
タネ
http://d.hatena.ne.jp/turing_pattern/20080523/1211547863
宣言と実装で引数の順番が違う、ってのはまぁわかると思います。
関数を呼ぶ時にどこ通るかって話で、 x86 では整数の浮動小数もスタックなる場所を通るんだけど、 x86_64 では整数と浮動小数が違う場所を通る。だから順番を変えても正しく動いてしまう。一方 x86 は、順番通りに渡ってしまうので、 1 を float と解釈して、 2.0f を double と解釈して、 3.0 を int として解釈して…ってことが起きて、
irb(main):015:0> [3.0].pack('d').unpack('ii') => [0, 1074266112]
というような理由で件の数値が。
sevilwm-0.9.5
id:mtkh さんに再起動時に引数保持するパッチをいただいたので。ていうか 0.9.3 とかも全然アナウンスしてないみたいだ。 ignore を腐らせてたのを mtkh さんに教えていただいて修正したのが 0.9.3 で、 click focus 時のリサイズ時にフォーカス変わっちゃう問題を修正していただいたのを取り込んだのが 0.9.4 みたいだ。非常に助かってます。ありがとうございます。