当你在Visual stuido 里面写完代码,摁 F5编译的时候,他的过程是,首先把C#代码编程IL代码,然后Jit接管被编译了的IL代码,调用函数,打印出结果。(QQ群676817308)
这里我们看下Jit是如何接管IL代码
接管的过程没有找到相应的代码,只能通过汇编来分析
首先,JIT会通过汇编指令Call 调用一个地址比如:
当我们进入到00007FFC1777CFB8
注意箭头的指向位置,同样他会调用call 指令跳转到地址00007FFC17752208。在此之前我们看下,箭头指向的5E这个是个机器指令,当前函数被编译过了这个5E会变成5F。5E上面的E8会变成E9。81机器码是methoddesc thunk 的索引,08是precode chunk的索引。继续看地址00007FFC17752208
可以看到jmp 指令调用了PrecodeFixupThunk函数,继续跳转到地址07FFC1EB71940h看PrecodeFixupThunk函数实现过程
这个 PrecodeFixupThunk函数分别获取了precodethunkindex和methoddescthunkindex。
然后调用ThePreStub函数。
ThePreStub调用了PreStubWorker,后者调用了SetTargetInterlocked,来修改函数的入口地址,把编译过的机器码直接放在jmp后面,以达到native运行目的。
BOOL FixupPrecode::SetTargetInterlocked(TADDR target, TADDR expected)
{
CONTRACTL
{
THROWS; // Creating a JumpStub could throw OutOfMemory
GC_NOTRIGGER;
}
CONTRACTL_END