При разборке кода .NET, имеющего дело с объектами и вызовами экземпляров, я обнаружил, что есть несколько вещей, которые я не совсем понимаю:
Вот мой тестовый код:
class Foo
{
public void Bar()
{
Console.WriteLine("hello");
}
}
...
var foo = new Foo();
foo.Bar();
А вот и разобранный результат (оптимизирован)
15: var foo = new Foo();
00000019 mov ecx,403880h //ecx = address of Foo type ?
0000001e call FFF71FB0 //call ctor ?
00000023 mov esi,eax //esi = result ?
16: foo.Bar();
00000025 call 63377060 //this seems to be console.writeline inlined (from bar)
0000002a mov ecx,eax
0000002c mov edx,dword ptr ds:[03612034h]
00000032 mov eax,dword ptr [ecx]
00000034 mov eax,dword ptr [eax+3Ch]
00000037 call dword ptr [eax+10h] // esi.Bar() ?
Я предполагаю, что первая часть касается загрузки типа Foo и последующего вызова конструктора для него?
А как же остальные?
Еще одна странная вещь заключается в том, что код генерирует следующий IL:
L_0017: callvirt instance void CSApp.Foo::Bar()
Почему он выполняет callvirt для не виртуального метода?
Это то, что происходит в нативном коде? поиск в vtable?