简体   繁体   中英

Where does this call come from?

I have some code that very roughly resembled the following:

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

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

The disassembly of the Main method, in Release mode, is as follows:

        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 

I don't understand why the call at nb is necessary. It seems like the address of bs and s are being passed as arguments, but as this is a simple pointer assignment, why is this necessary?

(This behaviour seems to happen for a lot of assignments to pointers. However, assigning null does not seem to follow this pattern.)

Guess: It is setting a bit the GC card table because you are creating a new reference from a heap field to a heap object.

You said "This behaviour seems to happen for a lot of assignments to pointers". This fits perfectly to this explanation.

If that string in the example is an std::string , then your innocent-looking assignment looks like this:

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

(It seems this specific compilation expect "this" in edx and argument in eax - probably the result of whole program optimization - the traditional convention is this in ecx and other arguments on the stack.)

C++ and STL give you nice and mostly effortless memory management. But it does not come for free. It's definitely not "a simple pointer assignment", no matter how it looks in the source code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM