Ortak Ara Dil - Common Intermediate Language
Eskiden Microsoft Intermediate Language ( MSIL ) veya Intermediate Language ( IL ) olarak adlandırılan Common Intermediate Language ( CIL ), Common Language Infrastructure (CLI) belirtiminde tanımlanan ara dil ikili komut kümesidir . CIL talimatları, Common Language Runtime gibi CLI uyumlu bir çalıştırma ortamı tarafından yürütülür . CLI'yi hedefleyen diller CIL'e derlenir. CIL, nesne yönelimli , yığın tabanlı bayt kodudur . Çalışma zamanları tipik olarak tam zamanında CIL talimatlarını yerel kodda derler .
CIL, .NET dillerinin beta sürümleri sırasında orijinal olarak Microsoft Orta Dili (MSIL) olarak biliniyordu. C # ve CLI'nin standardizasyonu nedeniyle , bayt kodu artık resmi olarak CIL olarak biliniyor. Windows Defender virüs tanımları, kendisiyle birlikte MSIL olarak derlenen ikili dosyalara başvurmaya devam etmektedir.
Genel bilgi
CLI programlama dillerinin derlenmesi sırasında , kaynak kodu platforma veya işlemciye özgü nesne kodu yerine CIL koduna çevrilir . CIL bir olduğu CPU gibi Ortak Dil Altyapı, destekleyen herhangi bir ortamda çalıştırılabilir ve platformdan bağımsız komut kümesi - .NET çalışma zamanı üzerinde Windows'un veya çapraz platform Mono çalışma zamanı. Teorik olarak bu, farklı platformlar ve CPU türleri için farklı yürütülebilir dosyalar dağıtma ihtiyacını ortadan kaldırır. CIL kodu, çalışma sırasında güvenlik açısından doğrulanır ve yerel olarak derlenen yürütülebilir dosyalardan daha iyi güvenlik ve güvenilirlik sağlar.
Yürütme süreci şuna benzer:
- Kaynak kodu CIL bayt koduna dönüştürülür ve bir CLI derlemesi oluşturulur.
- Bir CIL derlemesinin yürütülmesi üzerine, yerel kod üretmek için kodu çalışma zamanının JIT derleyicisinden geçirilir . Zamanın ilerisinde derleme de kullanılabilir, bu da bu adımı ortadan kaldırır, ancak yürütülebilir dosya taşınabilirliği pahasına.
- Bilgisayarın işlemcisi yerel kodu yürütür.
Talimatlar
CIL bayt kodu, aşağıdaki görev grupları için talimatlara sahiptir :
- Yükle ve sakla
- Aritmetik
- Tür dönüşümü
- Nesne oluşturma ve işleme
- Operand yığını yönetimi (push / pop)
- Kontrol aktarımı (dallanma)
- Yöntem çağırma ve dönüş
- İstisnalar atmak
- Monitör tabanlı eşzamanlılık
- C ++ / CLI ve güvenli olmayan C # kodu için gerekli veri ve işlev işaretçileri manipülasyonu
Hesaplamalı model
Ortak Ara Dil, nesne yönelimli ve yığın tabanlıdır ; bu, çoğu programlama dilinde olduğu gibi, komut parametrelerinin ve sonuçlarının birkaç yazmaç veya diğer bellek konumları yerine tek bir yığın üzerinde tutulduğu anlamına gelir .
Eax ve edx'in iki farklı genel amaçlı kaydı belirlediği x86 derleme dilinde iki sayı ekleyen kod :
add eax, edx
0'ın eax ve 1'in edx olduğu bir ara dilde (IL) kod :
ldloc.0 // push local variable 0 onto stack
ldloc.1 // push local variable 1 onto stack
add // pop and add the top two stack items then push the result onto the stack
stloc.0 // pop and store the top stack item to local variable 0
İkinci örnekte, eax ve edx olmak üzere iki yazmacın değerleri ilk önce yığın üzerine itilir. Ekleme talimatı çağrıldığında, işlenenler "açılır" veya geri alınır ve sonuç yığın üzerinde "itilir" veya depolanır. Ortaya çıkan değer daha sonra yığından çıkarılır ve eax'ta saklanır.
Nesneye yönelik kavramlar
CIL, nesne yönelimli olacak şekilde tasarlanmıştır. Nesneler oluşturabilir, yöntemleri çağırabilir ve alanlar gibi diğer üye türlerini kullanabilirsiniz.
Her yöntemin (bazı istisnalar dışında) bir sınıfta bulunması gerekir. Bu statik yöntem de öyle:
.class public Foo {
.method public static int32 Add(int32, int32) cil managed {
.maxstack 2
ldarg.0 // load the first argument;
ldarg.1 // load the second argument;
add // add them;
ret // return the result;
}
}
Add yöntemi, statik olarak bildirildiği için herhangi bir Foo örneğinin bildirilmesini gerektirmez ve daha sonra C # 'da şu şekilde kullanılabilir:
int r = Foo.Add(2, 3); // 5
CIL'de şöyle görünecektir:
ldc.i4.2
ldc.i4.3
call int32 Foo::Add(int32, int32)
stloc.0
Örnek sınıfları
Bir örnek sınıfı, en az bir yapıcı ve bazı örnek üyeleri içerir. Aşağıdaki sınıf, bir Car nesnesinin eylemlerini temsil eden bir dizi yönteme sahiptir.
.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 Brake() cil managed { /* Omitting implementation */ }
}
Nesne oluşturma
C # sınıfında örnekler şu şekilde oluşturulur:
Car myCar = new Car(1, 4);
Car yourCar = new Car(1, 3);
Ve bu ifadeler kabaca CIL'deki şu talimatlarla aynıdır:
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);
Örnek yöntemlerini çağırma
Örnek yöntemleri aşağıdaki gibi C # ile çağrılır:
myCar.Move(3);
CIL'de çağrıldığı gibi:
ldloc.0 // Load the object "myCar" on the stack
ldc.i4.3
call instance void Car::Move(int32)
Meta veriler
Ortak Dil Altyapı (CLI) olarak derlenmiş sınıfları hakkında bilgileri kaydeder meta veriler . Bileşen Nesne Modelindeki tür kitaplığı gibi , bu da uygulamaların montajdaki arabirimleri, sınıfları, türleri, yöntemleri ve alanları desteklemesini ve keşfetmesini sağlar. Bu tür meta verileri okuma sürecine " yansıma " denir .
Meta veriler, "öznitelikler" biçimindeki veriler olabilir. Nitelikler, Attribute
sınıfı genişleterek özelleştirilebilir . Bu güçlü bir özelliktir. Sınıfın yaratıcısına, sınıfın tüketicilerinin uygulama alanına bağlı olarak çeşitli anlamlı şekillerde kullanabilecekleri ekstra bilgilerle süsleme yeteneği sağlar.
Misal
Aşağıda, CIL ile yazılmış temel bir Merhaba, Dünya programı bulunmaktadır. "Merhaba dünya!" Dizesini gösterecektir.
.assembly Hello {}
.assembly extern mscorlib {}
.method static void Main()
{
.entrypoint
.maxstack 1
ldstr "Hello, world!"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
Aşağıdaki kod, işlem kodlarının sayısında daha karmaşıktır.
Bu kod, Java bayt kodu hakkındaki makaledeki karşılık gelen kodla da karşılaştırılabilir .
static void Main(string[] args)
{
for (int i = 2; i < 1000; i++)
{
for (int j = 2; j < i; j++)
{
if (i % j == 0)
goto outer;
}
Console.WriteLine(i);
outer:;
}
}
CIL sözdiziminde şuna benzer:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (int32 V_0,
int32 V_1)
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_001b
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)
IL_001b: ldloc.0
ldc.i4.1
add
stloc.0
IL_001f: ldloc.0
ldc.i4 0x3e8
blt.s IL_0004
ret
}
Bu, CIL'in sanal makine (VM) seviyesinin yakınında nasıl göründüğünün bir temsilidir . Derlendiğinde, yöntemler tablolarda saklanır ve talimatlar, bir Taşınabilir Yürütülebilir (PE) olan derlemenin içinde bayt olarak depolanır .
Nesil
Bir CIL derlemesi ve yönergeleri, bir derleyici veya yürütme ortamıyla birlikte gönderilen IL Assembler ( ILAsm ) adlı bir yardımcı program tarafından oluşturulur .
Montajlı CIL, IL Disassembler (ILDASM) kullanılarak tekrar koda ayrılabilir . CIL'i yüksek seviyeli bir dile (örn. C # veya Visual Basic ) dönüştüren .NET Reflector gibi başka araçlar da vardır . Bu, CIL'i tersine mühendislik için çok kolay bir hedef haline getirir. Bu özellik, Java bayt kodu ile paylaşılır . Bununla birlikte, kodu gizleyebilen ve bunu kodun kolayca okunamayacağı ancak yine de çalıştırılabilir olması için yapan araçlar vardır .
Yürütme
Tam zamanında derleme
Tam zamanında derleme (JIT), bayt kodunu CPU tarafından hemen çalıştırılabilir koda dönüştürmeyi içerir. Dönüştürme, programın yürütülmesi sırasında kademeli olarak gerçekleştirilir. JIT derlemesi, ortama özgü optimizasyon, çalışma zamanı tipi güvenliği ve montaj doğrulaması sağlar. Bunu başarmak için, JIT derleyicisi herhangi bir yasa dışı erişim için derleme meta verilerini inceler ve ihlalleri uygun şekilde ele alır.
Zamanın ilerisinde derleme
CLI uyumlu yürütme ortamları , çalışma zamanında JIT sürecini kaldırarak daha hızlı yürütülmesini sağlamak için bir derlemenin Zamanının Ötesinde derlemesi (AOT) yapma seçeneğiyle birlikte gelir .
In .NET Framework adı verilen özel bir alet var Özgün Görüntü Oluşturucu (NGEN) o gerçekleştirdiği AOT. AOT için farklı bir yaklaşım , .Net Core kodunun bir çalışma zamanına bağımlı olmaksızın tek bir yürütülebilir dosyada derlenmesine izin veren CoreRT'dir . In Mono aynı zamanda bir AOT yapmak için bir seçenek yoktur.
İşaretçi talimatları - C ++ / CLI
Java'nın bayt kodundan önemli bir fark, CIL'in, C / C ++ kodunu CIL'de derlemek için gereken veri / işlev işaretçileri manipülasyonu için yeterli olan ldind, stind, ldloca ve birçok çağrı talimatıyla birlikte gelmesidir.
class A {
public: virtual void __stdcall meth() {}
};
void test_pointer_operations(int param) {
int k = 0;
int * ptr = &k;
*ptr = 1;
ptr = ¶m;
*ptr = 2;
A a;
A * ptra = &a;
ptra->meth();
}
CIL'deki ilgili kod şu şekilde oluşturulabilir:
.method assembly static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
test_pointer_operations(int32 param) cil managed
{
.vtentry 1 : 1
// Code size 44 (0x2c)
.maxstack 2
.locals ([0] int32* ptr,
[1] valuetype A* V_1,
[2] valuetype A* a,
[3] int32 k)
// k = 0;
IL_0000: ldc.i4.0
IL_0001: stloc.3
// ptr = &k;
IL_0002: ldloca.s k // load local's address instruction
IL_0004: stloc.0
// *ptr = 1;
IL_0005: ldloc.0
IL_0006: ldc.i4.1
IL_0007: stind.i4 // indirection instruction
// ptr = ¶m
IL_0008: ldarga.s param // load parameter's address instruction
IL_000a: stloc.0
// *ptr = 2
IL_000b: ldloc.0
IL_000c: ldc.i4.2
IL_000d: stind.i4
// a = new A;
IL_000e: ldloca.s a
IL_0010: call valuetype A* modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) 'A.{ctor}'(valuetype A* modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst))
IL_0015: pop
// ptra = &a;
IL_0016: ldloca.s a
IL_0018: stloc.1
// ptra->meth();
IL_0019: ldloc.1
IL_001a: dup
IL_001b: ldind.i4 // reading the VMT for virtual call
IL_001c: ldind.i4
IL_001d: calli unmanaged stdcall void modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall)(native int)
IL_0022: ret
} // end of method 'Global Functions'::test_pointer_operations
Ayrıca bakınız
Referanslar
daha fazla okuma
- Bock, Jason (2002). CIL Programlama: .NET'in Altında . Apress. ISBN 978-1590590416 .