2012-03-19 7 views
-1

私は非常に大きく以下の類似していたいくつかのコードがあります。次のようにこの呼び出しはどこから来たのですか?

class C { 
    string s; 
    static C a = new C(); 

    static void Main() { 
     C b = a; 
     b.s = "hello"; 
} 

Main方法の解体は、リリースモードでは、次のとおりです。

 C b = a; 
00000000 push  ebp 
00000001 mov   ebp,esp 
00000003 push  eax 
00000004 cmp   dword ptr ds:[04581D9Ch],0 
0000000b je   00000012 
0000000d call  763B3BC3 
00000012 xor   edx,edx 
00000014 mov   dword ptr [ebp-4],edx 
00000017 mov   eax,dword ptr ds:[01B24E20h] ; Everything up to this point 
0000001c mov   dword ptr [ebp-4],eax  ; is fairly clear. 
     b.s = "hello"; 
0000001f mov   eax,dword ptr ds:[01B22088h] ; Loads the address of "hello" 
00000025 mov   ecx,dword ptr [ebp-4]  ; Loads the address of b 
00000028 lea   edx,[ecx+4]     ; Loads the address of (the reference to?) b.s 
0000002b call  76100AE0      ; ?? 
    } 
00000030 nop 
00000031 mov   esp,ebp 
00000033 pop   ebp 
00000034 ret 

なぜ呼び出し、私は理解していませんnbで必要です。 b.ssのアドレスが引数として渡されているようですが、これは単純なポインタ割り当てであるため、なぜこれが必要ですか?

は(この動作は、ポインタへの代入の多くのために起こるようですが、このパターンに従っていないようだ nullを割り当てる。。)

答えて

5

推測:あなたが作成しているので、それはビットにGCカードテーブルを設定していますヒープフィールドからヒープオブジェクトへの新しい参照。

あなたは「この動作はポインタへの多くの割り当てで発生するようです」と述べました。これはこの説明に完全に当てはまります。

+0

正しい説明のようです。 MSDNはそのメソッド(メソッド)にWrite Barrierを呼び出します。 –

+0

@HenkHolterman、あなたはリンクを提供できますか? – svick

+0

[ガベージコレクタの基本とパフォーマンスのヒント](http://msdn.microsoft.com/en-us/library/ms973837.aspx)ページの半分を下に –

0

の例とstringは、std::stringある場合は、あなたの無実に見える割り当ては次のようになります。

mov eax, offset "hello" 
mov ecx, b 
lea edx, [ecx+4] ; edx = &b.s 
call std::string::operator=(const char *) 

(この特定のコンパイルは「この」edxで、引数eaxに期待しているようだ - おそらく全体的なプログラム最適化の結果 - 伝統的なコンベンションでは、ecxやその他の引数がスタック上にあるthisです。)

C++とSTLを使用すると、簡単にメモリ管理ができます。しかしそれは無料ではありません。ソースコードでどのように見えても、それは間違いなく「単純なポインタ割り当て」ではありません。

+1

'std :: string'だった場合、完全に正しいだろうが、これはC#... :) –

関連する問題