Common Intermediate Language
Z Multimediaexpo.cz
Common Intermediate Language (CIL, vyslovováno jako „sil“, případně „kil“, dříve Microsoft Intermediate Language, MSIL) je v informatice nejnižší člověkem čitelný programovací jazyk definovaný specifikací Common Language Infrastructure používaný projekty .NET Framework a Mono. Jazyky, které se zaměřují na CLI kompatibilní prostředí, jsou sestavovány do byte kódu (Bytecode). CIL patří mezi objektově orientované jazyky výhradně zásobníkového typu (anglicky stack-based). Prováděn je prostřednictvím virtuálního stroje.
CIL byl původně během uvolňování beta .NET jazyků znám jako Microsoft Intermediate Language (MSIL). Vzhledem ke standardizaci C# a Common Language Infrastructure je byte-kód nově a oficiálně označován jako CIL.
Obsah |
Základní informace
Při kompilování .NET programovacích jazyků je zdrojový kód přeložen do CIL kódu (nepoužívá se platformně nebo do výpočetně specifický objektový kód). CIL je procesorově a zároveň platformě nezávislý soubor instrukcí, které mohou být realizovány v jakémkoli prostředí podporující Common Language Infrastructure (může se jednat buď o .NET runtime pro operační systém Microsoft Windows, nebo samostatně odvozené Mono, které pracuje pod operačními systémy jako Linux či Unix). CIL kód je za běhu ověřován z hlediska bezpečnosti, a proto poskytuje lepší zabezpečení a spolehlivost, než nativně kompilované binární soubory.
Proces spuštění vypadá takto:
- Zdrojový kód je převeden do Common Intermediate Language, CLI ekvivalent k nižším programovacím jazykům pro CPU.
- CIL je pak převeden do byte-kódu a je vytvořeno .NET assembly.
- Po provedení .NET assembly, jeho byte kód projde skrz provozní JIT kompilátor, aby generoval nativní kód.
- Nativní kód je zpracováván pomocí procesoru.
Instrukce
CIL bytecode má instrukce pro následující skupiny úloh:
- Načítání a ukládání
- Aritmetické
- Typ konverze
- Vytváření objektů a manipulaci s nimi
- Operand managementu zásobníku (push / pop)
- Kontrola převodu (větvení - Branching)
- Volání metod
- Vyhazování výjimky
- Synchronizace
Výpočetní model
Common Intermediate Language je považován za objektově orientovaný jazyk zásobníkového typu (stack-based). To znamená, že data jsou ukládána z registrů do zásobníku místo toho, aby byla odkládána do paměti jako ve většině CPU architektur.
V architektuře x86 by to mohlo vypadat následovně:
add eax, edx mov ecx, eax
Odpovídající kód v CIL by mohl vypadat takto:
ldloc.0 ldloc.1 add stloc.0 // a = a + b or a += b;
V programu jsou použity dvě lokálně proměnné, které jsou přesunuty do fronty. Když je přidaná instrukce zavolána, operand je ze zásobníku vyzvednut a výsledek je na něj obratem uložen. Hodnota je pak vyzvednuta a uložena jako první lokální proměnná.
Objektově-orientované koncepty
V objektově-orientovaném konceptu můžete vytvářet objekty, volat metody a používat další typy členů, jako jsou například pole. CIL je navržen jako objektově orientovaný a všechny metody (až na výjimky) musí být obsažené v příslušné třídě.
Příklad statické metody:
.class public Foo { .method public static int32 Add(int32, int32) cil managed { .maxstack 2 .locals init ( [0] int32 num1, [1] int32 num2 ) ldloc.0 ldloc.1 add stloc.0 // a = a + b or a += b; ret // return a; } }
Použitá metoda nevyžaduje žádnou deklaraci instance třídy Foo, protože je statická. To znamená, že náleží do třídy a může být následně použita jako v tomto případě v C#.
int r = Foo.Add(2, 3); //5
V CIL
ldc.i4.2 ldc.i4.3 call int32 Foo::Add(int32, int32) stloc.0
Instance tříd
Instance třídy obsahuje nejméně jeden konstruktor a nějaké další členy. Tato třída má sadu metod reprezentujících akce objektu Car.
.class public Car { .method public specialname rtspecialname instance void .ctor(int32, int32) cil managed { /* Constructor */ } .method public void Move(int32) cil managed { /* Omitting implementation */ } .method public void TurnRight() cil managed { /* Omitting implementation */ } .method public void TurnLeft() cil managed { /* Omitting implementation */ } .method public void Break() cil managed { /* Omitting implementation */ } }
Vytváření objektů
Instance tříd jsou v C# vytvářeny následujícím způsobem:
Car myCar = new Car(1, 4); Car yourCar = new Car(1, 3); <source lang="csharp"> Příkazy jsou přibližně stejné jako tyto instrukce: <source lang="cil"> ldc.i4.1 ldc.i4.4 newobj instance void Car::.ctor(int, int) stloc.0 // myCar = new Car(1, 4); ldc.i4.1 ldc.i4.3 newobj instance void Car::.ctor(int, int) stloc.1 // yourCar = new Car(1, 3);
Vyvolání metody instance
Například metody jsou volány následovně:
myCar.Move(3);
V CIL
ldloc.0 // Load the object "myCar" on the stack ldc.i4.3 call instance void Car::Move(int32)
Metadata
.NET zaznamenává informace o kompilovaných třídách jako metadata. Proces čtení těchto metadat se nazývá zrcadlení (reflection). Metadata mohou být data v podobě atributů. Ty mohou být volně rozšířeny o atributy třídy, čímž se stávají velmi silným nástrojem.
Příklad
Příklad je napsán v CIL a demonstruje kód „Hello, World“:
.assembly Hello {} .assembly extern mscorlib {} .method static void Main() { .entrypoint .maxstack 1 ldstr "Hello, world!" call void [mscorlib]System.Console::WriteLine(string) ret }
Tento kód může být porovnán s odpovídajícím kódem Java Bytecode:
static void Main(string[] args) { outer: for (int i = 2; i < 1000; i++) { for (int j = 2; j < i; j++) { if (i % j == 0) goto outer; } Console.WriteLine(i); } }
V CIL-syntaxi by zápis vypadal následovně:
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint .maxstack 2 .locals init (int32 V_0, int32 V_1) IL_0000: ldc.i4.2 stloc.0 br.s IL_001f IL_0004: ldc.i4.2 stloc.1 br.s IL_0011 IL_0008: ldloc.0 ldloc.1 rem brfalse.s IL_0000 ldloc.1 ldc.i4.1 add stloc.1 IL_0011: ldloc.1 ldloc.0 blt.s IL_0008 ldloc.0 call void [mscorlib]System.Console::WriteLine(int32) ldloc.0 ldc.i4.1 add stloc.0 IL_001f: ldloc.0 ldc.i4 0x3e8 blt.s IL_0004 ret }
Výše je správná reprezentace toho, jak vypadá CIL blízko VM úrovně. Když jsou zkompilované metody uloženy v tabulkách a instrukce zase v bytech uvnitř assembly, který je přenosně spustitelným souborem (Portable Executable-file).
Vývoj
CIL assembly a instrukce jsou generovány buď kompilátorem nebo nástrojem zvaným jako IL Assembler (ILASM). Složené IL může být také znovu rozloženo do kódu užitím IL Disassembler (ILDASM). Existují další nástroje jako .NET Reflektor, které umožní dekompilaci IL do jazyků vyšší úrovně (např. C#, Visual Basic). Tato vlastnost je sdílená s Java bytecode. Ale existují nástroje, které mohou zmást kód, a to tak, že vlastní kód nemůže být rozložen, ale přesto je spustitelný.
Kompilace just-in-time
Kompilace just-in-time kompilace zahrnuje vrácení byte-kódu do kódu, který je okamžitě vykonatelný pomocí CPU. Konverze je prováděna postupně v průběhu vykonávání programu. JIT kompilace nabízí specifické optimalizace daného prostředí a ověření assembly. K dosažení tohoto, JIT kompilátor zkoumá nashromážděná metadata pro nezákonné přístupy a ovládá přiměřeně rušení.
Externí odkazy
- Common Language Infrastructure (Standard ECMA-335)
- “ECMA C# and Common Language Infrastructure Standards” on MSDN
- Hello world program in CIL
- Kenny Kerr's intro to CIL (called MSIL in the tutorial)
- Speed: NGen Revs Up Your Performance With Powerful New Features -- MSDN Magazine, April 2005
- http://en.csharp-online.net/CIL_Instruction_Set
Náklady na energie a provoz naší encyklopedie prudce vzrostly. Potřebujeme vaši podporu... Kolik ?? To je na Vás. Náš FIO účet — 2500575897 / 2010 |
---|
Informace o článku.
Článek je převzat z Wikipedie, otevřené encyklopedie, do které přispívají dobrovolníci z celého světa. |