(続き) 2ちゃんねる、GCCスレより

ふーむ。-fcall-saved-XXX ってのは知らなかったな。「(calling conventionを)普通CPUメーカーが決める」という件についてはそうですね。x86についても「IA-32 インテル(R)アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル 上巻」の6章、「プロシージャ・コール、割り込み」に説明があります。

584 名前:デフォルトの名無しさん 投稿日:04/05/19 21:49
GCCの生成するコードの、ABI資料はありません?


587 名前:デフォルトの名無しさん 投稿日:04/05/20 18:25
http://www.caldera.com/developers/devspecs/
http://www.codesourcery.com/cxx-abi/
この辺しか知らない


588 名前:584 投稿日:04/05/20 20:00
>>585,586
そのものズバリです、i386の関数呼出ABIです
>>587
おお!素晴らしい!読んでみますです


C関数コール時にに各レジスタの内容を、アセンブルコード側で保証しなくてはならないのか、GCCの吐くコード側で保証されるのか知りたかったのです。それとEBP(フレームポインタ)の扱いも。(gcc -S foo.c で出力されるコードでは、(E)AX以外の内容も保証されていませんでしたが VCの吐いたPEコードを逆アセンブルした時は、呼出先で保証していた気が...)


アセンブルするのは不慣れなんで、ABI仕様を読めば、 その辺りの規定が書いてあるんじゃないかと考えた次第です。どうもDebian上のGCC3.3.3 で -Os -O3 を付けた場合、書いたコードの挙動が怪しくて...最適化に左右されないCコードの呼出を行うには、関数呼出規定を熟知しておこうと...


589 名前:デフォルトの名無しさん 投稿日:04/05/20 21:35
まとまった文章は読んだことないけど、i386 だとeax, ecx, edx が関数内で壊していいレジスタ、ebx, esi, edi が関数内で変えちゃいけないレジスタ。これは、Windows でも *BSD でも Linux でも同じはず。

gcc-3.3.x のソースだと、gcc/config/i386/i386.h のCALL_USED_REGISTERS の値かね。

こういうのって、Intel が決めたのかなあ?


590 名前:デフォルトの名無しさん 投稿日:04/05/20 21:56
>>589
ふつうCPUメーカが決める。大抵CPUのマニュアルに書いてあるよ。


591 名前:デフォルトの名無しさん 投稿日:04/05/20 21:59
>>589
なんてコッタ、EAX,ECX,EDXって保証する必要無いんですね..
Intelアーキテクチャマニュアル上巻見直します...

>>gcc-3.3.x のソースだと、gcc/config/i386/i386.h の
>>CALL_USED_REGISTERS の値かね。

gcc -S -fcall-saevd-ecx -fcall-saved-edx -fcall-saved-ebx foo.c

で、 指定レジスタ使用時にpush/popされるのを確認しました -fcall-used-reg で破壊可能レジスタとなるそうです。アセンブル時に、保護したいレジスタはスタックフレームにセーブしなくてはならないってことですね。まずはマニュアルを見直します