Maison  >  Article  >  développement back-end  >  CLR (common Language Runtime) et IL (code intermédiaire) en C#

CLR (common Language Runtime) et IL (code intermédiaire) en C#

黄舟
黄舟original
2017-02-07 15:44:011911parcourir

CLR dans la plateforme .net

Tout d'abord, il convient de noter que la plateforme .NET n'est pas la même chose que C#. C'est la plateforme sur laquelle s'exécutent des programmes tels que C# et VB.net. .

CLR est le Common Language Runtime et une partie importante du .NET Framework. Il fournit des services tels que la gestion de la mémoire, la gestion des threads et la gestion des exceptions, et est également responsable de la mise en œuvre de contrôles stricts de sécurité de type sur le code pour garantir l'exactitude du code.

En fait, de nombreuses fonctionnalités en C# telles que la sécurité des types (Type Checker), le garbage collection (Garbage Collector), la gestion des exceptions (Exception Manager), la rétrocompatibilité (COM Marshaler), etc. sont fournies par le CLR. .

Qu'est-ce qu'IL

.NET Framework est une plate-forme d'exécution virtuelle construite sur la plate-forme Windows. Vous pouvez imaginer remplacer la couche inférieure de Windows par d'autres systèmes d'exploitation, tels que Linux, de la même manière. possible d'utiliser un langage .NET conforme à CLS (Common Language Spécification, Common Language Spécification). C'est en fait la fonction que Mono envisage de réaliser. Par conséquent, en théorie, C# est un langage multiplateforme.

Une autre chose qui rend C# plus proche de Java est qu'il s'agit également d'un langage (dans un sens particulier, comme Java, le code du programme écrit en C# est d'abord compilé en un caractère spécial par la section C#). le code, (Microsoft Intermediate Language, MSIL, Microsoft) langage intermédiaire, est compilé en code machine par un compilateur spécifique (compilateur JIT, Just In tIME, JITer) au moment de l'exécution pour exécution par le système d'exploitation.

IL est un langage intermédiaire. Les compilateurs de divers langages de haut niveau (tels que C#, VB, F#) sur la plateforme .NET convertiront leurs expressions de texte respectives en IL. Diverses formes de texte ont finalement été unifiées dans l'expression d'IL

Après que CLR ait chargé IL, lorsque chaque méthode est exécutée pour la première fois, JIT sera utilisé pour compiler le code IL en code machine et en assemblage. avoir une correspondance biunivoque. Cela peut être compris comme ceci : l'assembly est la représentation textuelle du code machine et fournit des « mnémoniques » dont les gens peuvent se souvenir facilement.

Pour le même IL, JIT générera différents codes machine pour différentes architectures CPU (telles que x86/IA64, etc.).

Code C# et son code intermédiaire IL correspondant

CLR (common Language Runtime) et IL (code intermédiaire) en C#

//hidebysig指令表示如果当前类为父类,用该指令标记的方法将不会被子类继承
//cil managed表明方法体中的代码是IL代码,且是托管代码,即运行在CLR运行库上的代码
.method private hidebysig static void Main(string[] args)cil managed
{
    .entrypoint //该指令代表该函数程序的入口函数。每一个托管应用程序都有且只有一个入口函数,CLR加载程序时,首先从.entrypoint函数开始执行。
    .maxstack 2 //执行构造函数时,评估堆栈可容纳数据项的最大个数。评估堆栈是保存方法中所需要变量的值的一个内存区域,该区域在方法执行结束时会被清空,
    或者存储一个返回值。
    .locals init (
        [0] int32 num,
        [1] int32 num2,
        [2] int32 num3) //表示定义int类型的变量,变量名分别为num,num2,num3。存储在调用栈。
    L_0000: nop  //No operation的意思,即没有任何操作。
    L_0001: ldc.i4.1  //将“1”压入评估栈,此时“1”处于评估栈的栈顶。
    L_0002: stloc.0  //此指令表示把值从评估栈中弹出,并赋值给调用栈的第0个变量num。
    L_0003: ldc.i4.2
    L_0004: stloc.1
    L_0005: ldc.i4.3
    L_0006: stloc.2 //从.locals init到L_0006,相当于C#代码的为i,j,k赋值。
    L_0007: ldloc.0  //取调用栈中位置为0的元素压入评估栈(取i的值)。
    L_0008: ldloc.1  //取调用栈中位置为1的元素压入评估栈(取j的值)。
    L_0009: add  //做加法操作
    L_000a: ldloc.2 //取调用栈中位置为2的元素压入评估栈(取k的值)。
    L_000b: add  //做加法操作
    L_000c: call void [mscorlib]System.Console::WriteLine(int32) //调用输出方法
    L_0011: nop  //No Operation
    L_0012: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ReadKey方法
    L_0017: pop //把评估栈的内容清空
    L_0018: ret  //return 标记返回值
} //Main方法结束

Grâce au code ci-dessus, on peut résumer : .maxstack : variables dans le code dont il a besoin pour occuper plusieurs positions dans la pile d'appels (Call Stack) ; .locals int(...) : Définir l'initialisation de la variable et la mettre dans la pile d'appels (Call Stack) ; Poussez la chaîne dans la pile d'évaluation ;


ldc.i4.1 : poussez la valeur 2 dans la pile d'évaluation sous la forme d'un entier de 4 octets ; insérez la valeur dans la pile d'évaluation (Evaluation) et attribuez-la à la pile d'appels (Call Stack) ; ldloc : retirez (copiez) la valeur à la position spécifiée dans la pile d'appels (Call Stack) et poussez-la dans la pile d'évaluation ; (Pile d'évaluation) ; call : appelle la méthode spécifiée. Cette instruction est généralement utilisée pour appeler des méthodes statiques ; callvir est généralement utilisé pour appeler des méthodes d'instance ;

Regardons un autre exemple

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();
        }
    }
}

Le code IL de la méthode principale correspondante :

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 8
    // 分配字符串"Before JITed"
    L_0000: ldstr "Before JITed."
    // 调用Console.WriteLine方法
    L_0005: call void [mscorlib]System.Console::WriteLine(string)
    // 调用Console.ReadLine方法
    L_000a: call string [mscorlib]System.Console::ReadLine()
    L_000f: pop
    // 调用Program.SomeMethod方法
    L_0010: call void TestConsole.Program::SomeMethod()
    // 分配字符串"After JITed"
    L_0015: ldstr "After JITed"
    // 调用Console.WriteLine方法
    L_001a: call void [mscorlib]System.Console::WriteLine(string)
    // 调用Console.ReadLine方法
    L_001f: call string [mscorlib]System.Console::ReadLine()
    L_0024: pop
    L_0025: ret
}

Ce qui précède est le CLR (langage commun) en C# Runtime) et IL (code intermédiaire), veuillez faire attention au site Web PHP chinois (www.php.cn) pour plus de contenu connexe !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn