.Net 7里的函数.Ctor和.CCtor是干啥用的呢?你知道吗( 二 )

它里面就调用了一个Call , 也就是这句话:
callqword ptr [7FFDF2DD1030h]这个十六进制的7FFDF2DD1030h是个啥呢?继续跟进下:0x00007FFDF2DD103000007ffe50357230它里面包含了一个地址00007ffe50357230看下这个地址的汇编代码:
00007FFE50357230 C3ret它直接返回了 。
所以这得出了一个什么结论呢?也就是说在当前这个例子中 , .Ctor啥都没做 。
.CCtor目的来看下静态的默认构造函数干了些啥 。先上代码:
internal class Program{static string a ="abcd";static void Main(string[] args){string i = a;Console.WriteLine(a);Console.ReadLine();}}同样反编译下:
00007FFDF01903B0 55pushrbp00007FFDF01903B1 57pushrdi00007FFDF01903B2 48 83 EC 28subrsp,28h00007FFDF01903B6 48 8D 6C 24 30learbp,[rsp+30h]00007FFDF01903BB 33 C0xoreax,eax00007FFDF01903BD 48 89 45 F0movqword ptr [rbp-10h],rax00007FFDF01903C1 48 89 4D 10movqword ptr [rbp+10h],rcx00007FFDF01903C5 83 3D C4 E9 19 00 00 cmpdword ptr [7FFDF032ED90h],000007FFDF01903CC 74 05je00007FFDF01903D300007FFDF01903CE E8 BD BF 7D 5EcallJIT_DbgIsJustMyCode (07FFE4E96C390h)00007FFDF01903D3 90nop00007FFDF01903D4 48 B9 60 EF 32 F0 FD 7F 00 00 movrcx,7FFDF032EF60h00007FFDF01903DE BA 04 00 00 00movedx,4// 可以看到这个 string 静态对象并没有调用.CCtor 。// 那是否说明上面的说法不对呢?注意看 , 他实际调用了// JIT_GetSharedNonGCStaticBase_SingleAppDomain,// 而这个就是关键所在00007FFDF01903E3 E8 48 7E C5 5EcallJIT_GetSharedNonGCStaticBase_SingleAppDomain (07FFE4EDE8230h)00007FFDF01903E8 8B 0D AA EB 19 00movecx,dword ptr [7FFDF032EF98h]00007FFDF01903EE FF 15 7C 94 60 00callqword ptr [7FFDF0799870h]00007FFDF01903F4 90nop00007FFDF01903F5 FF 15 9D 93 60 00callqword ptr [7FFDF0799798h]00007FFDF01903FB 48 89 45 F0movqword ptr [rbp-10h],rax00007FFDF01903FF 90nop00007FFDF0190400 90nop00007FFDF0190401 48 83 C4 28addrsp,28h00007FFDF0190405 5Fpoprdi00007FFDF0190406 5Dpoprbp00007FFDF0190407 C3ret00007FFDF0190408 19 06sbbdword ptr [rsi],eax看这段代码上面的注释 , 这段代码里面并没有.CCtor被调用的痕迹 。而它的奥秘在JIT_GetSharedNonGCStaticBase_SingleAppDomain函数里面 。
JIT_GetSharedNonGCStaticBase_SingleAppDomain又调用了JIT_GetSharedNonGCStaticBase_Helper
看下堆栈
> coreclr.dll!MethodTable::RunClassInitEx 行 3591 C++coreclr.dll!MethodTable::DoRunClassInitThrowing 行 3792 C++coreclr.dll!MethodTable::CheckRunClassInitThrowing 行 3929 C++coreclr.dll!JIT_GetSharedNonGCStaticBase_Helper 行 1401 C++函数 RunClassInitEx代码如下:
BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable){//为了方便观看 此处省略部分代码PCODE pCctorCode = pCanonMT->GetSlot(pCanonMT->GetClassConstructorSlot());//为了方便观看 此处省略部分代码PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(pCctorCode);DECLARE_ARGHOLDER_ARRAY(args, 0);CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;CALL_MANAGED_METHOD_NORET(args);//为了方便观看 此处省略部分代码变量pCctorCode就是.CCtor的函数头地址 。而后面的一堆的宏定义实际上是调用了函数 DispatchCallSimple , 而DispatchCallSimple又调用了CallDescrWorkerWithHandler然后又调用了PrecodeFixupThunk下面调用了PreStubWorker
PreStubWorker通过 call rax命令跳转到调用的函数的函数头地址 , 比如本例的 .CCtor函数头的地址 。
00007FFE8BB289C0 E8 DB FE 8F FFcallPreStubWorker (07FFE8B4288A0h)00007FFE8BB289C5 66 0F 6F 44 24 20movdqaxmm0,xmmword ptr [rsp+20h]00007FFE8BB289CB 66 0F 6F 4C 24 30movdqaxmm1,xmmword ptr [rsp+30h]00007FFE8BB289D1 66 0F 6F 54 24 40movdqaxmm2,xmmword ptr [rsp+40h]00007FFE8BB289D7 66 0F 6F 5C 24 50movdqaxmm3,xmmword ptr [rsp+50h]00007FFE8BB289DD 48 8B 8C 24 B0 00 00 00 movrcx,qword ptr [rsp+0B0h]00007FFE8BB289E5 48 8B 94 24 B8 00 00 00 movrdx,qword ptr [rsp+0B8h]00007FFE8BB289ED 4C 8B 84 24 C0 00 00 00 movr8,qword ptr [rsp+0C0h]00007FFE8BB289F5 4C 8B 8C 24 C8 00 00 00 movr9,qword ptr [rsp+0C8h]00007FFE8BB289FD 48 83 C4 68addrsp,68h00007FFE8BB28A01 5Fpoprdi00007FFE8BB28A02 5Epoprsi00007FFE8BB28A03 5Bpoprbx00007FFE8BB28A04 5Dpoprbp00007FFE8BB28A05 41 5Cpopr1200007FFE8BB28A07 41 5Dpopr1300007FFE8BB28A09 41 5Epopr1400007FFE8BB28A0B 41 5Fpopr15// 这个rax 就是 .CCtor的函数头的地址00007FFE8BB28A0D 48 FF E0jmprax

经验总结扩展阅读