免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

C#中CLR(公共語(yǔ)言運(yùn)行時(shí))與IL(中間代碼)

 weijianian 2016-08-07


來(lái)源:lxydo

鏈接:http://blog.csdn.net/pwiling/article/details/51461722


.net平臺(tái)中的CLR


首先要說(shuō)明的是,.NET平臺(tái)與C#不是一回事 它是C#,VB.net等程序運(yùn)行的平臺(tái)。


CLR是公共語(yǔ)言運(yùn)行時(shí),是 .NET Framework的重要組成部分。它提供了內(nèi)存管理、線程管理和異常處理等服務(wù),而且還負(fù)責(zé)對(duì)代碼實(shí)施嚴(yán)格的類型安全檢查,保證了代碼的正確性。


事實(shí)上,類型安全(Type Checker)、垃圾回收(Garbage Collector)、異常處理(Exception Manager)、向下兼容(COM Marshaler)等很多C#中的特性都是由CLR來(lái)提供的。


什么是IL


.NET Framework是架構(gòu)在Windows平臺(tái)上的一個(gè)虛擬的運(yùn)行平臺(tái),你可以想象將最下層Windows換做其他的操作系統(tǒng),例如說(shuō)Linux,一樣可以實(shí)現(xiàn)使用符合CLS(Common Language Specification,通用語(yǔ)言規(guī)范)的.NET語(yǔ)言,這其實(shí)就是Mono計(jì)劃要實(shí)現(xiàn)的功能。因而,理論上,C#是一種可以跨平臺(tái)的語(yǔ)言。


C#另一個(gè)比較象Java的地方是,它也是一種(特殊意義上的)語(yǔ)言,同Java一樣,C#編寫的程序代碼也是先通過(guò)C#編譯器編譯為一種特殊的字節(jié)代碼, (Microsoft Intermediate Language,MSIL,微軟)中間語(yǔ)言,運(yùn)行時(shí)再經(jīng)由特定的編譯器(JIT編譯器,Just In tIME, JITer)編譯為機(jī)器代碼,以供操作系統(tǒng)執(zhí)行。


IL是一門中間語(yǔ)言 ,.NET平臺(tái)上的各種高級(jí)語(yǔ)言(如C#,VB,F(xiàn)#)的編譯器會(huì)將各自的文字表述方式轉(zhuǎn)化為IL。各種不同的文字形式最終被統(tǒng)一到了IL的表述方式


CLR加載了IL之后,當(dāng)每個(gè)方法第一次被執(zhí)行時(shí),就會(huì)使用JIT將IL代碼進(jìn)行編譯為機(jī)器碼,機(jī)器碼和匯編其實(shí)也是一一對(duì)應(yīng)的,可以這樣理解:匯編是機(jī)器碼的文字表現(xiàn)形式,提供了一些方便人們記憶的“助記符”。


對(duì)于同樣的IL,JIT會(huì)把它為不同的CPU架構(gòu)(如x86/IA64等等)生成不同的機(jī)器碼。


C#代碼及其對(duì)應(yīng)的IL中間代碼



//hidebysig指令表示如果當(dāng)前類為父類,用該指令標(biāo)記的方法將不會(huì)被子類繼承

//cil managed表明方法體中的代碼是IL代碼,且是托管代碼,即運(yùn)行在CLR運(yùn)行庫(kù)上的代碼

.method private hidebysig static void Main(string[] args)cil managed

{

    .entrypoint //該指令代表該函數(shù)程序的入口函數(shù)。每一個(gè)托管應(yīng)用程序都有且只有一個(gè)入口函數(shù),CLR加載程序時(shí),首先從.entrypoint函數(shù)開始執(zhí)行。

    .maxstack 2 //執(zhí)行構(gòu)造函數(shù)時(shí),評(píng)估堆??扇菁{數(shù)據(jù)項(xiàng)的最大個(gè)數(shù)。評(píng)估堆棧是保存方法中所需要變量的值的一個(gè)內(nèi)存區(qū)域,該區(qū)域在方法執(zhí)行結(jié)束時(shí)會(huì)被清空,或者存儲(chǔ)一個(gè)返回值。

    .locals init (

        [0] int32 num,

        [1] int32 num2,

        [2] int32 num3) //表示定義int類型的變量,變量名分別為num,num2,num3。存儲(chǔ)在調(diào)用棧。

    L_0000: nop  //No operation的意思,即沒有任何操作。

    L_0001: ldc.i4.1  //將“1”壓入評(píng)估棧,此時(shí)“1”處于評(píng)估棧的棧頂。

    L_0002: stloc.0  //此指令表示把值從評(píng)估棧中彈出,并賦值給調(diào)用棧的第0個(gè)變量num。

    L_0003: ldc.i4.2

    L_0004: stloc.1

    L_0005: ldc.i4.3

    L_0006: stloc.2 //從.locals init到L_0006,相當(dāng)于C#代碼的為i,j,k賦值。

    L_0007: ldloc.0  //取調(diào)用棧中位置為0的元素壓入評(píng)估棧(取i的值)。

    L_0008: ldloc.1  //取調(diào)用棧中位置為1的元素壓入評(píng)估棧(取j的值)。

    L_0009: add  //做加法操作

    L_000a: ldloc.2 //取調(diào)用棧中位置為2的元素壓入評(píng)估棧(取k的值)。

    L_000b: add  //做加法操作

    L_000c: call void [mscorlib]System.Console::WriteLine(int32) //調(diào)用輸出方法

    L_0011: nop  //No Operation

    L_0012: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //調(diào)用ReadKey方法

    L_0017: pop //把評(píng)估棧的內(nèi)容清空

    L_0018: ret  //return 標(biāo)記返回值

} //Main方法結(jié)束


通過(guò)上面的代碼,我們可以總結(jié)一下: .maxstack:代碼中變量需要在調(diào)用棧(Call Stack)中占用幾個(gè)位置; .locals int(……):定義變量初始化并放入調(diào)用棧中(Call Stack); nop:No Operation,沒有任何操作; ldstr:Load String,把字符串壓入評(píng)估棧(Evaluation Stack)中;


ldc.i4.1:把數(shù)值2以4字節(jié)長(zhǎng)度整數(shù)的形式壓入評(píng)估棧; stloc:把評(píng)估棧(Evaluation)中的值彈出賦值到調(diào)用棧中(Call Stack); ldloc:把調(diào)用棧(Call Stack)中指定位置的值取出(Copy)壓入評(píng)估棧(Evaluation Stack)中; call:調(diào)用指定的方法,這個(gè)指令一般用于調(diào)用靜態(tài)方法;而callvir則一般用于調(diào)用實(shí)例方法; ret:return ,標(biāo)記返回。


下面再看一個(gè)例子


namespace TestConsole

{

    class Program

    {

        [MethodImpl(MethodImplOptions.NoInlining)]

        private static void SomeMethod()

        {

            Console.WriteLine('Hello World!');

        }

 

        static void Main(string[] args)

        {

            Console.WriteLine('Before JITed.');

            Console.ReadLine();

 

            SomeMethod();

 

            Console.WriteLine('After JITed');

            Console.ReadLine();

        }

    }

}


與之相對(duì)應(yīng)的main方法IL代碼:


.method private hidebysig static void Main(string[] args) cil managed

{

    .entrypoint

    .maxstack 8

    // 分配字符串'Before JITed'

    L_0000: ldstr 'Before JITed.'

    // 調(diào)用Console.WriteLine方法

    L_0005: call void [mscorlib]System.Console::WriteLine(string)

    // 調(diào)用Console.ReadLine方法

    L_000a: call string [mscorlib]System.Console::ReadLine()

    L_000f: pop

    // 調(diào)用Program.SomeMethod方法

    L_0010: call void TestConsole.Program::SomeMethod()

    // 分配字符串'After JITed'

    L_0015: ldstr 'After JITed'

    // 調(diào)用Console.WriteLine方法

    L_001a: call void [mscorlib]System.Console::WriteLine(string)

    // 調(diào)用Console.ReadLine方法

    L_001f: call string [mscorlib]System.Console::ReadLine()

    L_0024: pop

    L_0025: ret

}


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多