2015-12-29 2 views
5

他の人が同様の質問を書いていることは知っていますが、解決策が見つからないため、私は別のケースだと思います。Cで参照が割り当てられているときに不思議な呼び出しが追加される

私はこのような非常にシンプルなもの、オブジェクトの割り当てを持っている:ちょうど何が起こっているか理解するために、

_buffer3 = buffer; //they are just simple reference types 

アセンブリコード生成は、現在、以下の

mov   edx,dword ptr [ebp-3Ch] 
mov   eax,dword ptr [ebp-40h] 
lea   edx,[edx+4] 
call  69C322F0 

である私がしたかったです、コール内の一歩(なぜ割り当て内でコールを使用する必要がありますか)。しかし、そのアドレスのコードが存在していないと私はステップすることはできません 私はアドレスコード欄にアドレスを入力した場合、それが示されているものです:。

69C322F0 ??? 

この謎を解決しようとして任意のヘルプ? :)

編集。クラスのメソッド内で参照が割り当てられていると、不思議な呼び出しが追加されるようです。

私は、このクラスを使用している場合:

 private class Test 
     { 
      int _X; 
      int _Y; 
      Test _t; 

      public void SetValues(int x, int y, Test t) 
      { 
       _X = x; 
       _Y = y; 
      } 
     } 

アセンブリは、メソッドSetValues用に生成は次のとおりです。私はこの

 private class Test 
     { 
      int _X; 
      int _Y; 
      Test _t; 

      public void SetValues(int x, int y, Test t) 
      { 
       _X = x; 
       _Y = y; 
       _t = t; 
      } 
     } 
を書く場合は意味

を作る

   _X = x; 
00000028 mov   eax,dword ptr [ebp-3Ch] 
0000002b mov   edx,dword ptr [ebp-40h] 
0000002e mov   dword ptr [eax+8],edx 
       _Y = y; 
00000031 mov   eax,dword ptr [ebp-3Ch] 
00000034 mov   edx,dword ptr [ebp+0Ch] 
00000037 mov   dword ptr [eax+0Ch],edx 

神秘的な呼び出しは、ガベージコレクションに関連する何か私見

   _X = x; 
00000028 mov   eax,dword ptr [ebp-3Ch] 
0000002b mov   edx,dword ptr [ebp-40h] 
0000002e mov   dword ptr [eax+8],edx 
       _Y = y; 
00000031 mov   eax,dword ptr [ebp-3Ch] 
00000034 mov   edx,dword ptr [ebp+0Ch] 
00000037 mov   dword ptr [eax+0Ch],edx 
       _t = t; 
0000003a mov   edx,dword ptr [ebp-3Ch] 
0000003d mov   eax,dword ptr [ebp+8] 
00000040 lea   edx,[edx+4] 
00000043 call  515E2E48 

を表示されますが、私はそれが何であるかを理解できないと私は本当にそれを把握したいと思います。私はこのAについての麺ます

This is an extract I took from Google Books of the book: CLR via C#

+0

hmmいいえ、実際には無効にしています。私はそれを試してみます! – sebas

+0

@AlexD、プロジェクトプロパティ([デバッグ]タブ)で[管理されていないコードのデバッグを有効にする]をチェックしましたか? –

+0

[この質問]の複製である場合があります(http://stackoverflow.com/questions/57840/how-to-attach-debugger-to-step-into-native-c-code-from-a-managed-c -wrappe) –

答えて

4

を:私はあなたの誰かが知っている必要があります知っている:)

補遺の答えに、これは私がC#の経由ブックCLRのGoogleブックスから取った抽出物であります少しずつ、完全な答えがみんなを眠らす本を埋めます。あなたはマシンコードについて非常に不正確な見方をしていますが、32ビットディスアセンブラはCALLアドレスを変換する仕事が非常に貧弱です。あなたが64ビットコードを見れば、最近のVSバージョンではかなり改善されています。マシンコード命令のアドレスを偽装することはもうありません。そこで:

  • プロジェクト]> [プロパティ]> [タブを作成します。プラットフォームターゲット= AnyCPU、チェックを外し、「優先32ビットの」
  • プロジェクト]> [プロパティ]> [デバッグ]タブ:ダニ「ネイティブコードのデバッグを有効にする」
  • ツール>オプション>デバッグ>シンボル:Microsoft Symbol Serverを有効にします。
  • ツール>オプション>デバッグ>一般:「JIT最適化を抑制する」のチェックを外します。

あなたは本当マシンコード、ユーザーのマシン上で動作するようなものを見たい場合は、最後の設定変更が必要なだけです。今すぐ最適化されていないデバッグコードを見ていることに注意してください。そうでなければこの質問に関係するものではない。

それは理想からまだ遠いですが、それはかなりよくディスアセンブラを照らします。あなたのTest.SetValuesのテールエンド()メソッドは次のようになります。

   _t = t; 
00007FFA1ECB0C58 mov   rdx,qword ptr [rbp+50h] 
00007FFA1ECB0C5C lea   rcx,[rdx+8] 
00007FFA1ECB0C60 mov   rdx,qword ptr [rbp+68h] 
00007FFA1ECB0C64 call  JIT_WriteBarrier (07FFA7E3312B0h) 

表示されたアドレスは、今0x07FFA7E3312B0正確です。そのコードを見るにはもう一つのステップが必要です。デバッガを強制的にネイティブモードにする必要があります。デバッグ> Windows>コールスタックを選択し、RtlUserThreadStartのようにトレースの下部にあるネイティブ関数をダブルクリックします。今度は "07FFA7E3312B0"を逆アセンブラのアドレスボックスにコピー/ペーストすることができます。最初に "0x"を入力してください。私はここには示しませんが、これはコードからリバースエンジニアリングすることはできない、不思議なことをする手書きのアセンブリコードです。

これらのジッタヘルパー関数を探すのに適した場所はソースコードですが、完全一致ではありませんが、github CoreCLR projectが最適です。 hereになります。

一般に、ジッタは必要に応じてこの種のダイレクトCLR関数呼び出しを発行し、その名前は通常「JIT」で始まります。これはアセンブリで書かれていますが、これはあまり一般的ではありません。ほとんどがC++で書かれています。

+0

ありがとう、非常に便利な答え。私にはWriteBarrierについて知るには十分でしたが、デバッグの説明は上のチェリーです。 – sebas

+1

いつもあなたの答えを読んで、毎回新しいことを学ぶ喜び:) –

関連する問題