2016-08-22 8 views
2

The "this" pointerCLRのABIドキュメント内の「この」ポインタ

AMD64のみ:.NET Frameworkの4.5までは、管理「この」ポインタが だけでネイティブのようにそれを意味する「この」ポインタを(処理しました。コールが返信バッファを使用し、RCXの代わりにRDX に渡されたときに、2番目の 引数でした。

私は「この」ポインタは、コールが復帰バッファを使用していた第二引数だった、それは.NET Frameworkの4.5までであることを私の理解に基づいて、CLRのABIドキュメントに上記のステートメントを見つけましたRDXで渡された。

だから私は二つの質問があります。

  1. をバッファの意味は何ですか? httpwebresponseなどのストリームバッファーを参照するバッファーですか?

  2. 私たちが静的クラスを使用すると、 "this"ポインタが存在せず、上記のステートメントがインスタンスオブジェクトに指定されているのでしょうか?

+0

リターンバッファは、x64呼び出し規約のMSDNドキュメントの[Return Values](https://msdn.microsoft.com/en-us/library/7572ztz4.aspx)に記載されています。*それ以外の場合、呼び出し元はメモリを割り当て、最初の引数として戻り値のポインタを渡す責任があります。 –

答えて

8

Microsoftがx64 abiを手直ししていることは明らかです。彼らが何をしたのか、そしていつははっきりとはっきりしていないのか、ドキュメンテーションは不完全で、ばらばらになっていて、日付が間違いです。私は個人的にAgner Fogによって行われたreverse-engineering workを本当に信頼できる情報源とみなしています。しかし、マネージドコードの生成には取り組んでいません。

これが4.5で変更されたという主張は、むしろ信じられないほどです。より多くの可能性があるのは、これはRyuJIT(新しいx64ジッタ)で変更されました。これは、かなりバグがあり、維持できないレガシーx64ジッタを置き換えます。もともと4.5.3としてプレビューされ、おそらく4.5の主張を説明していましたが、後で4.6に増加しました。この変更の可能性が高いのは、.NETCoreプロジェクトです.UNIXコードジェネレータ(GNUとLLVM)とのMicrosoft x64 abiの違いはかなり苦しいです。

しかし、C++コンパイラコードジェネレータの変更(Agner Fog、gackによるVS2015アップデートで修正)とは異なり、この変更はかなり壊れそうにありません。不一致はピンボケでのみ発生する可能性があり、ジッタは決してCallingConventionをサポートしませんでした。幸いにも、あなたの質問は簡単に答えることができます:

バッファの意味は?

これは、「集約タイプ」を返すメソッドに対してのみ重要です。言い換えれば、CPUに合わない値はもはやレジスタになります。 structであるC#では、(2人以上のメンバーまたは非自明なフィールドタイプである)それほど重要ではないというさらなる規定があります。

メソッド呼び出し側は、戻り値( "バッファ")のスタックフレームに領域を割り当て、その領域にポインタを渡す必要があります。そのポインタは、隠された余分な引数としてメソッドに渡されます。伝統的に最初の引数、隠されたthis引数の前。これはthisを2番目の引数にしたため、RCXレジスタの代わりにRDXレジスタを通過しました。変更により、順序が逆になります。thisは常に最初の引数でRCXに渡され、戻り値ポインタは2番目です。呼び出されたメソッドは、戻り値が返される前にそのバッファに戻り値をコピーします。

どのように静的方法に、我々は静的クラスを使用する場合

についてのみ該当します。余分な隠されたthisの引数がないので、単に省略されます。これまでのやり方から効果的に変更はありません。隠れた戻り値ポインタは常に自動的に第1引数であり、したがってRCXに渡されます。

この場合、デバッガの[デバッグ]> [Windows]> [逆アセンブリ]ウィンドウを必ず利用してください。小さなテストプログラムで実行すると、どのレジスタが使用されているかが簡単にわかります。

関連する問題