A mysterious call is added when a link is assigned in C #

I know that other people wrote similar questions, but I think mine is a different case, since I did not find any solution.

I have an object assignment, something very simple:

_buffer3 = buffer; //they are just simple reference types 

generated assembly code is as follows

  mov edx,dword ptr [ebp-3Ch] mov eax,dword ptr [ebp-40h] lea edx,[edx+4] call 69C322F0 

Now, to understand what was going on, I wanted to enter the call (why should the call be used in the task?). However, the code at this address does not exist, and I cannot enter. if I type the address in the address code field, then what is shown:

 69C322F0 ??? 

Any help trying to solve this mystery? :)

Change ... so a mysterious call is added when a link is assigned inside a class method.

If I have this class:

  private class Test { int _X; int _Y; Test _t; public void SetValues(int x, int y, Test t) { _X = x; _Y = y; } } 

assembly generated for the SetValues โ€‹โ€‹method:

  _X = x; 00000028 mov eax,dword ptr [ebp-3Ch] 0000002b mov edx,dword ptr [ebp-40h] 0000002e mov dword ptr [eax+8],edx _Y = y; 00000031 mov eax,dword ptr [ebp-3Ch] 00000034 mov edx,dword ptr [ebp+0Ch] 00000037 mov dword ptr [eax+0Ch],edx 

what makes sense

however, if I write this

  private class Test { int _X; int _Y; Test _t; public void SetValues(int x, int y, Test t) { _X = x; _Y = y; _t = t; } } 

a mysterious call appears

  _X = x; 00000028 mov eax,dword ptr [ebp-3Ch] 0000002b mov edx,dword ptr [ebp-40h] 0000002e mov dword ptr [eax+8],edx _Y = y; 00000031 mov eax,dword ptr [ebp-3Ch] 00000034 mov edx,dword ptr [ebp+0Ch] 00000037 mov dword ptr [eax+0Ch],edx _t = t; 0000003a mov edx,dword ptr [ebp-3Ch] 0000003d mov eax,dword ptr [ebp+8] 00000040 lea edx,[edx+4] 00000043 call 515E2E48 

IMHO this is something related to garbage collection, but I canโ€™t understand what it is, and I really would like to understand it. I know that one of you should know :)

Adding to the answer. This is an excerpt that I took from Google Books CLR Books through C #:

This is an excerpt from a Google Books book: CLR via C #

+5
source share
1 answer

I will work on this a bit, the full answer fills the book, which makes everyone sleep. You get a very inaccurate representation of machine code, a 32-bit disassembler does a very poor job translating CALL addresses. This has improved a bit in recent versions of VS, if you look at 64-bit code that no longer fakes machine address instructions. Get there with:

  • Project> Properties> Build tab: platform target = "AnyCPU", "Disable" "Prefer 32-bit"
  • Project> Properties> Debug Tab: check "Enable Native Code Debugging"
  • Tools> Options> Debugging> Symbols: enable Microsoft Symbol Server
  • Tools> Options> Debugging> General: disable "Disable JIT optimization".

The last change in the settings is necessary only if you want to look at the real machine code that runs on your computer user. Beware that you are viewing unoptimized debugging code right now. Otherwise, this does not apply to this issue.

This will illuminate the disassembler well, although it is still far from ideal. The tail of your Test.SetValues โ€‹โ€‹() method now looks like this:

  _t = t; 00007FFA1ECB0C58 mov rdx,qword ptr [rbp+50h] 00007FFA1ECB0C5C lea rcx,[rdx+8] 00007FFA1ECB0C60 mov rdx,qword ptr [rbp+68h] 00007FFA1ECB0C64 call JIT_WriteBarrier (07FFA7E3312B0h) 

The displayed address is now exact, 0x07FFA7E3312B0. Looking at this code, one more additional step is required, you must force the debugger in the main mode. Debugging> Windows> Call the stack and double-click the built-in function at the bottom of the trace, for example RtlUserThreadStart. Now you can copy / paste "07FFA7E3312B0" into the "Address" field of the disassembler, first enter "0x". I will not show it here, this is handwritten assembly code that does a rather mysterious thing that you can never recode from code.

The best place to look for these helper jitter features is source code, although it is not an exact match, the github CoreCLR project is your best bet. You take here .

In general, jitter emits these direct CLR calls as needed, and their name usually starts with "JIT". This is one of them written in the meeting, but it is not very common; most of them are written in C ++.

+4
source

Source: https://habr.com/ru/post/1239382/


All Articles