暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

.NET Core CLR 解析

DotNet开发跳槽 2021-08-05
937

.net Core CLR是开源的。大部分文件是C++写成。这样他就可以编译后再不同的平台运行。

  https://github.com/dotnet/coreclr.

 

一些基础概念的理解:

1.IL 是中间语言,是高级语言,不能一句一句执行的,要有上下文,解析的CLR 大概和Python 的解释器相似,比如 在C# 中,定义一个var a=0.7 ; 对应的IL 就是  ldc.r8 0.7。

  有如下的代码:

public class Test
{
int i = 8;
int j = 9;
string s="asd";
public void Main(string[] args)
{
Console.WriteLine(i);
Console.WriteLine(j);
Console.WriteLine(s);
var t = 0.7;
Console.WriteLine(t);
}

public Test()
{
this.i = 12;
Console.WriteLine(
"ss");
}
}

当执行 this.i = 12;这句话的时候,this 已经存在了!怎么做到的呢?我们看下对应的IL:

    .method public hidebysig specialname rtspecialname 
instance
void .ctor () cil managed
{
// Method begins at RVA 0x20cf
Code size 54 (0x36)

.maxstack 8

// i = 8;
IL_0000: ldarg.0
IL_0001: ldc.i4.
8
IL_0002: stfld int32 TestConsoleApp.Test::i
// j = 9;
IL_0007: ldarg.0
IL_0008: ldc.i4.s
9
IL_000a: stfld int32 TestConsoleApp.Test::j
// s = "asd";
IL_000f: ldarg.0
IL_0010: ldstr
"asd"
IL_0015: stfld
string TestConsoleApp.Test::s
// base..ctor();
IL_001a: ldarg.0
IL_001b: call instance
void [System.Runtime]System.Object::.ctor()
// (no C# code)
IL_0020: nop
IL_0021: nop
// i = 12;
IL_0022: ldarg.0 指令将索引为0的参数推送到计算堆栈上。 ldarg.0
 指令可用于将值类型或基元值从传入参数复制到堆栈上

IL_0023: ldc.i4.s
12 将从-128 到127的整数推送到计算堆栈上
IL_0025: stfld int32 TestConsoleApp.Test::i 将对象 field
 的值替换为新值。
// Console.WriteLine("ss");
IL_002a: ldstr "ss"
IL_002f: call
void [System.Console]System.Console::WriteLine(string)
// (no C# code)
IL_0034: nop
// }
IL_0035: ret
}
// end of method Test::.ctor

在执行 

IL_0022: ldarg.0 之前,已经执行了 一部分代码了,只是我们看不到!在类中字段的默认值,也是在这里执行的。
这里更可以看到 call instance void [System.Runtime]System.Object::.ctor(),这是执行字段初始化后调用父类Object 的构造方法。
这个和JS中的New 有点像似呢!这个也是构造函数.

function Person (){

this.name
="zs";
this.age
=12;

}

var p= new  Person();

并且New 的时候,会有下面的翻译,语法有些C++ 的味道

// Test test = new Test();
IL_001d: newobj instance void TestConsoleApp.Test::.ctor()

 那个构造函数IL是下面的代码

    .method public hidebysig 
instance
void Main () cil managed
{
// Method begins at RVA 0x2098
Code size 55 (0x37)

.maxstack 1
.locals init (
[
0] float64 t
)

// (no C# code)
IL_0000: nop
// Console.WriteLine(i);
IL_0001: ldarg.0
IL_0002: ldfld int32 TestConsoleApp.Test::i
IL_0007: call
void [System.Console]System.Console::WriteLine(int32)
// (no C# code)
IL_000c: nop
// Console.WriteLine(j);
IL_000d: ldarg.0
IL_000e: ldfld int32 TestConsoleApp.Test::j
IL_0013: call
void [System.Console]System.Console::WriteLine(int32)
// (no C# code)
IL_0018: nop
// Console.WriteLine(s);
IL_0019: ldarg.0
IL_001a: ldfld
string TestConsoleApp.Test::s
IL_001f: call
void [System.Console]System.Console::WriteLine(string)
// (no C# code)
IL_0024: nop
// double value = 0.7;
IL_0025: ldc.r8 0.7 将 num
 作为 F
推送到堆栈上。

IL_002e: stloc.
0 将值从堆栈中弹出到局部变量0中。
// Console.WriteLine(value);
IL_002f: ldloc.0 将索引 0 处的局部变量加载到计算堆栈上。
IL_0030: call
void [System.Console]System.Console::WriteLine(float64)
// (no C# code)
IL_0035: nop
// }
IL_0036: ret
}
// end of method Test::Main

 

2.引用类型中的值类型是存在堆中。这就像我们正在读的书是栈,参考书是堆,我们在家里读一本书,上面有一句话:请参考 《####》第100页,这是个引用,我们打开 那本参考书的100页,里面会有对我们直接有用的信息,还是在哪本参考书(堆)中。

3.单例,指的是引用类型,在堆上。多线程共享堆,就是可以同时访问的。就像好几个人在读书,但是参考书只有一本。

出处:https://www.cnblogs.com/qgbo/p/11553861.html


版权申明:本文来源于网友收集或网友提供,仅供学习交流之用,如果有侵权,请转告版主或者留言,本公众号立即删除。


支持小微:

腾讯云 搞活动了?玩服务器的可以搞搞。就这几天时间。

轻量  1C2G6M 60GB SSD盘297元/3年

链接:https://curl.qcloud.com/bR8ycXZa


右下角,您点一下在看图片

小微工资涨1毛

商务合作QQ:185601686



文章转载自DotNet开发跳槽,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论