2012-03-19 2 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.s и s передаются в качестве аргументов, но поскольку это простое назначение указателя, зачем это необходимо?

(Такое поведение, кажется, происходит в течение многих присвоений указателей Однако, назначение null, кажется, не следовать этому образцу..)

ответ

5

Guess: Это установка бита таблицы GC-карты, потому что вы создаете новая ссылка из поля кучи на объект кучи.

Вы сказали: «Такое поведение, похоже, происходит для множества назначений указателям». Это прекрасно подходит для этого объяснения.

+0

Похоже, правильное объяснение. MSDN вызывает это (метод) барьер записи. –

+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 - вероятно, результат оптимизации всей программы - традиционное соглашение - this в ecx и другие аргументы в стеке.)

C++ и STL дают вам приятное и в основном легкое управление памятью. Но это не бесплатно. Это определенно не «простое назначение указателя», как бы оно ни выглядело в исходном коде.

+1

Если это была строка 'std :: string', вы было бы совершенно правильно, но это C# ... :) –

 Смежные вопросы

  • Нет связанных вопросов^_^