Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

249
Visualizações
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 à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda