Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

250
Vistas
Why do assignments to reference-type fields in .NET have all that extra assembly code?

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:

  • Why are there extra operations after the assignment to C.O's backing field? What's their meaning?
  • Why isn't it simply mov dword ptr [esi+4], eax, similar to assigning to C.N (a value-type field)?
  • What's the meaning of the value at address (edx >> 0Ah) + 33223E0h?
  • Does this happen to all reference-type field assignments?

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.

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda