Here's a simple C# class:
public class C
{
public object O { get; set; }
public int N { get; set; }
}
Here's a C# statement initializing a C instance:
var c = new C { O = new object(), N = 0x11223344 };
And here's its x86 disassembly, with optimizations enabled (retrieved through Visual Studio's "Disassembly" window):
01A70851 mov ecx,1654E00h
01A70856 call CORINFO_HELP_NEWSFAST (016430F4h)
01A7085B mov esi,eax
01A7085D mov ecx,73042734h
01A70862 call CORINFO_HELP_NEWSFAST (016430F4h)
01A70867 lea edx,[esi+4]
=> 01A7086A call 7485EC00
01A7086F mov dword ptr [esi+8],11223344h
Here's the code at address 7485EC00:
7485EC00 mov dword ptr [edx],eax
7485EC02 cmp eax,371100Ch
7485EC08 jb 7485EC17
7485EC0A shr edx,0Ah
7485EC0D nop
7485EC0E cmp byte ptr [edx+33223E0h],0FFh
7485EC15 jne 7485EC1A
7485EC17 ret
7485EC18 nop
7485EC19 nop
7485EC1A mov byte ptr [edx+33223E0h],0FFh
7485EC21 ret
Here's the state of the registers just before calling 7485EC00:
EAX = 037123D4 EBX = 0137F570 ECX = 73042734 EDX = 037123C8
ESI = 037123C4 EDI = 0137F4E0
EIP = 01A7086A ESP = 0137F4C4 EBP = 0137F4C8 EFL = 00000216
From my understanding, the function at address 7485EC00 starts by assigning the reference to the newly created object (stored in eax) to C.O's backing field (esi+4). That's expected. What surprised me are all the extra operations after it.
In my case, eax was 037123D4h, which is not less than 371100Ch, so the code doesn't take the jump 7485EC08 jb 7485EC17 and thus continues to check/set the address at (edx >> 0Ah) + 33223E0h to 0FFh.
Here are my questions:
C.O's backing field? What's their meaning?mov dword ptr [esi+4], eax, similar to assigning to C.N (a value-type field)?(edx >> 0Ah) + 33223E0h?By the way, this happens both for .NET Framework and for .NET Core, both for x86 and x64 (as checked through https://sharplab.io/).
Just to be clear: I'm not having any problem. It's just for curiosity.