CIL Common Intermediate Language All roads lead to

  • Slides: 57
Download presentation
CIL – Common Intermediate Language All roads lead to Rome (proverb). NET Framework &

CIL – Common Intermediate Language All roads lead to Rome (proverb). NET Framework & CLR: All languages lead to Intermediate Language

„All languages lead to Intermediate Language“ Die semantischen Eigenschaften der CILInstruktionen sind wichtig (für

„All languages lead to Intermediate Language“ Die semantischen Eigenschaften der CILInstruktionen sind wichtig (für den Compiler-Writer) Der JIT- (Just-In-Time)Compiler transformiert CILCode in semantisch äquivalenten native Code für die konkrete Zielumgebung.

Common Intermediate Language Die Common Intermediate Language (CIL) ist Teil des Standards ECMA-335. Die

Common Intermediate Language Die Common Intermediate Language (CIL) ist Teil des Standards ECMA-335. Die vollständige Spezifikation der CIL ist unter www. ecma-international. org zu finden: ECMA-335, CLI Partition III: CIL Instruction Set This Standard ECMA-335. . . defines the Common Language Infrastructure (CLI) in which applications written in multiple high-level languages may be executed in different system environments without the need to rewrite the applications to take into consideration the unique characteristics of those environments. (ECMA-335, CLI Partition I: Concepts and Architecture, p. 1) Die Common Language Runtime (CLR) ist die Implementierung der CLI von Microsoft. Die Common Intermediate Language ist die einheitliche Zwischensprache, die CLR versteht.

Virtual Execution System (VES) Das VES ist die execution engine der Common Language Runtime.

Virtual Execution System (VES) Das VES ist die execution engine der Common Language Runtime. Der Zustand dieser execution engine bezüglich eines Methodenaufrufs ist durch zwei Teile gekennzeichnet: 1. Activation Record (Aktivierungssatz) 2. Evaluation Stack Der Befehl call der IL allokiert einen neuen Aktivierungssatz beim Aufruf einer Methode (method call). Ein Aktivierungssatz besteht aus null oder mehreren Methodenargumenten und keinen oder mehreren lokalen Variablen der Methode. Auf dem Evaluation Stack liegen keine oder mehrere stack elements (Stackelemente), auf die Instruktionen durchgeführt werden. Lokalen Variable und Argumenten einer Methode sind logisch nummeriert (beginnend bei 0).

Virtual Execution System (VES) Activation record (im „Method State“

Virtual Execution System (VES) Activation record (im „Method State“

Einteilung des Instruktionssatzes nach der Wirkung auf den evaluation stack: Befehle, die. . .

Einteilung des Instruktionssatzes nach der Wirkung auf den evaluation stack: Befehle, die. . . 1. Operationen auf vorhandenen Werten auf dem Stack durchführen (zum Beispiel add) 2. einen Wert auf den Stack pushen (von der Art load) 3. einen Wert vom Stack poppen und an einer bestimmten Stelle speichern (store-Befehle) Bestimmte Befehle wie pop (einfaches Entfernen vom evaluation stack) und dup (Duplizieren des obersten Elements am evaluation stack) lassen sich nicht eindeutig zuordnen. Notation zur Beschreibung von Befehlen des Instruktionssatzes: (stack transition diagram). . . , value 1, value 2 . . . , result „Stack-Delta“ D Differenz der Anzahl der Elemente auf dem evaluation stack nach Ausführung eines Befehls i und vor Ausführung eines Befehls i. Beispiel add: D = - 1

CIL – Load & Store Instruktionen (1) public static void Test. Method (int a,

CIL – Load & Store Instruktionen (1) public static void Test. Method (int a, int b) // arguments { int c; int d; int e; // locals c = a + b; d = 10; e = c + d; } ldarg num load argument no. num onto the stack … …, value ldarg. 1 ldloc indx … …, value ldloc. 1 load local variable no. indx onto the stack

CIL – Load & Store Instruktionen (2) ldc num load numeric constant … …,

CIL – Load & Store Instruktionen (2) ldc num load numeric constant … …, num ldc. i 4 10 stloc indx pop value from stack to local variable stloc. 0 …, value … stloc. 0 starg num …, value … starg. 1 store a value in an argument slot starg. 1

CIL – Beispiel public static void Test. Method (int a, int b) { int

CIL – Beispiel public static void Test. Method (int a, int b) { int c; int d; int e; c = a + b; d = 10; e = c + d; }. method public hidebysig static void Test. Method (int 32 a, int 32 b) cil managed { // Code size 12 (0 xc) . maxstack 2. locals init ([0] int 32 c, [1] int 32 d, [2] int 32 e) IL_0000: ldarg. 0 IL_0001: ldarg. 1 IL_0002: add IL_0003: stloc. 0 IL_0004: ldc. i 4. s 10 IL_0006: stloc. 1 IL_0007: ldloc. 0 IL_0008: ldloc. 1 IL_0009: add IL_000 a: stloc. 2 IL_000 b: ret } // end of method Class 1: : Test. Method evaluation stack

ldind. * / stind. * (1) Es gibt beim Laden / Speichern von Werten

ldind. * / stind. * (1) Es gibt beim Laden / Speichern von Werten auch die Möglichkeit der Indirektion (Dereferenzierung). Dazu dienen die Befehle ldind. * und stind. *:

ldind. * / stind. * (2) Managed C++-Code: entsprechender CIL-Code: int x = 99;

ldind. * / stind. * (2) Managed C++-Code: entsprechender CIL-Code: int x = 99; . maxstack 2 int* px = &x; . locals ([0] int 32* px, [1] int 32 x) *px = 40; IL_0000: ldc. i 4. s 99 IL_0002: stloc. 1 IL_0003: ldloca. s x // dieser Befehl ermittelt die Adresse // der Variable x, = transient pointer IL_0005: stloc. 0 IL_0006: ldloc. 0 IL_0007: ldc. i 4. s 40 IL_0009: stind. i 4 IL_000 a: ldc. i 4. 0 IL_000 b: ret

Von der CLR verwendete Datentypen § bool § char, string § object, typedref §

Von der CLR verwendete Datentypen § bool § char, string § object, typedref § int 8, int 16, int 32, int 64 (alle ebenfalls auch unsigned: unsigned int 8, . . . ) § float 32, float 64 § native int, native unsigned int

Datentypen auf dem evaluation stack des VES § int 32, int 64, native int

Datentypen auf dem evaluation stack des VES § int 32, int 64, native int (i - native size integers), interner Typ F (float, native size floating point numbers) § Object references (o) § pointer types (native unsigned integers, &) Beim Laden / Speichern auf den / vom Evaluation Stack werden Datentypen entsprechend konvertiert.

Klassen – Objekte newobj ctor object create a new . . . , arg

Klassen – Objekte newobj ctor object create a new . . . , arg 1, . . . arg. N . . . , obj Allocate an uninitialized object and call ctor (Konstruktor)

Klassen – Objekte public class Test. Class { int a, b; public Test. Class(int

Klassen – Objekte public class Test. Class { int a, b; public Test. Class(int c, int d) { a = c; b = d; } } Test. Class Test. Object = new Test. Class(10, 40); . maxstack 3. locals init ([0] class Demo. Application 5. Class 1/Test. Class Test. Object) IL_0000: ldc. i 4. s 10 IL_0002: ldc. i 4. s 40 IL_0004: newobj instance void Demo. Application 5. Class 1/Test. Class: : . ctor(int 32, int 32) IL_0009: stloc. 0 IL_000 a: ret

Klassen – Objekte Code im Hauptprogramm: Klassendefinition: Demo. Class Demo. Object; public class Demo.

Klassen – Objekte Code im Hauptprogramm: Klassendefinition: Demo. Class Demo. Object; public class Demo. Class Demo. Object = new Demo. Class(); { public static int Stat. Demo. Variable; Demo. Class. Stat. Demo. Variable = 7; Demo. Object. Obj. Demo. Variable = 8; stfld field store into a field of an object …, obj, value …, Speichert den Wert value im Feld field des Objektes obj stsfld field store into a static field of an object …, value …, Speichert den Wert value im statischen Feld field einer Klasse public int Obj. Demo. Variable; }

Klassen – Objekte Code im Hauptprogramm: Demo. Class Demo. Object; Demo. Object = new

Klassen – Objekte Code im Hauptprogramm: Demo. Class Demo. Object; Demo. Object = new Demo. Class(); Demo. Class. Stat. Demo. Variable = 7; Demo. Object. Obj. Demo. Variable = 8; . maxstack 2. locals init ([0] class Demo. Application 2. Class 1/Demo. Class Demo. Object) IL_0000: newobj instance void Demo. Application 2. Class 1/Demo. Class: : . ctor() IL_0005: stloc. 0 IL_0006: ldc. i 4. 7 IL_0007: stsfld int 32 Demo. Application 2. Class 1/Demo. Class: : Stat. Demo. Variable IL_000 c: ldloc. 0 IL_000 d: ldc. i 4. 8 IL_000 e: stfld IL_0013: ret int 32 Demo. Application 2. Class 1/Demo. Class: : Obj. Demo. Variable

Klassen – Objekte Code im Hauptprogramm: ldfld field load field of an object .

Klassen – Objekte Code im Hauptprogramm: ldfld field load field of an object . . . , obj . . . , value int x; pusht den Wert von field von obj, oder des value type, obj, auf den Stack int y; ldsfld field load static field of a class Demo. Class Demo. Object; . . . , value Demo. Object = new Demo. Class(); pusht den Wert eines statischen Felds field eines Objekts auf den Stack x = 14 + Demo. Object. Obj. Demo. Variable; y = 15 + Demo. Class. Stat. Demo. Variable;

Klassen – Objekte Code im Hauptprogramm: . maxstack 2. locals init ([0] int 32

Klassen – Objekte Code im Hauptprogramm: . maxstack 2. locals init ([0] int 32 x, int x; [1] int 32 y, int y; [2] class Demo. Application 2. Class 1/Demo. Class Demo. Object) IL_0000: newobj instance void Demo. Application 2. Class 1/Demo. Class: : . ctor() Demo. Class Demo. Object; IL_0005: stloc. 2 Demo. Object = new Demo. Class(); IL_0006: ldc. i 4. s 14 IL_0008: ldloc. 2 x = 14 + Demo. Object. Obj. Demo. Variable; IL_0009: ldfld y = 15 + Demo. Class. Stat. Demo. Variable; IL_000 e: add int 32 Demo. Application 2. Class 1/Demo. Class: : Obj. Demo. Variable IL_000 f: stloc. 0 IL_0010: ldc. i 4. s 15 IL_0012: ldsfld IL_0017: add IL_0018: stloc. 1 IL_0019: ret int 32 Demo. Application 2. Class 1/Demo. Class: : Stat. Demo. Variable

Methodenaufruf – method call 1. call method call a method . . . ,

Methodenaufruf – method call 1. call method call a method . . . , arg 1, arg 2, . . . , argn . . . , ret. Val (not always returned) 2. callvirt method call a method associated, at runtime, with an object . . . , obj, arg 1, arg 2, . . . , arg. N . . . , return. Value (not always returned) calli callsitedescr indirect method call . . . , arg 1, arg 2, . . . , argn, ftn . . . , ret. Val (not always returned)

Methodenaufruf – method call Code im Hauptprogramm: . maxstack 2. locals init ([0] int

Methodenaufruf – method call Code im Hauptprogramm: . maxstack 2. locals init ([0] int 32 x, int x = 10; [1] int 32 y) int y = 30; IL_0000: ldc. i 4. s 10 IL_0002: stloc. 0 Demo. Reference(ref x, ref y); IL_0003: ldc. i 4. s 30 IL_0005: stloc. 1 IL_0006: ldloca. s x IL_0008: ldloca. s y IL_000 a: call void Demo. Application 2. Class 1: : Demo. Reference(int 32&, int 32&) IL_000 f: ret

Methodenaufruf – method call public class Time { public int Time. In. Seconds(int hours,

Methodenaufruf – method call public class Time { public int Time. In. Seconds(int hours, int minutes, int seconds) { return (hours * 3600 + minutes * 60 + seconds); } } Code im Hauptprogramm: Time First. Time = new Time(); int hours = 5; int minutes = 47; int seconds = 7; First. Time. In. Seconds(hours, minutes, seconds);

method call . maxstack 4. locals init ([0] class Demo. Application 2. Class 1/Time

method call . maxstack 4. locals init ([0] class Demo. Application 2. Class 1/Time First. Time, [1] int 32 hours, [2] int 32 minutes, [3] int 32 seconds) Code im Hauptprogramm: IL_0000: newobj instance void Demo. Application 2. Class 1/Time: : . ctor() IL_0005: stloc. 0 IL_0006: ldc. i 4. 5 Time First. Time = new Time(); int hours = 5; int minutes = 47; int seconds = 7; First. Time. In. Seconds(hours, minutes, seconds); IL_0007: stloc. 1 IL_0008: ldc. i 4. s 47 IL_000 a: stloc. 2 IL_000 b: ldc. i 4. 7 IL_000 c: stloc. 3 IL_000 d: ldloc. 0 this – Zeiger: IL_000 d: ldloc. 0 IL_000 e: ldloc. 1 IL_000 f: ldloc. 2 IL_0010: ldloc. 3 IL_0011: callvirt instance int 32 Demo. Application 2. Class 1/Time: : Time. In. Seconds(int 32, int 32) IL_0016: pop IL_0017: ret

method call . method public hidebysig instance int 32 Time. In. Seconds(int 32 hours,

method call . method public hidebysig instance int 32 Time. In. Seconds(int 32 hours, int 32 minutes, int 32 seconds) cil managed CIL-Code der Methode Time. In. Seconds(int 32 hours, int 32 minutes, int 32 seconds); { // Code size 19 (0 x 13) . maxstack 3. locals init ([0] int 32 CS$00000003$0000) IL_0000: ldarg. 1 IL_0001: ldc. i 4 0 xe 10 IL_0006: mul Argument 0 IL_0007: ldarg. 2 IL_0008: ldc. i 4. s 60 IL_000 a: mul IL_000 b: add IL_000 c: ldarg. 3 IL_000 d: add IL_000 e: stloc. 0 IL_000 f: br. s this – Zeiger = IL_0011: ldloc. 0 IL_0012: ret } // end of method Time: : Time. In. Seconds

Methodenaufruf – method call public class Time { private int h; public int Time.

Methodenaufruf – method call public class Time { private int h; public int Time. In. Seconds(int hours) { this. h = 33; return (hours * 3600); } Code im Hauptprogramm: } Time First. Time = new Time(); int hours = 5; First. Time. In. Seconds(hours);

method call . method public hidebysig instance int 32 Time. In. Seconds(int 32 hours)

method call . method public hidebysig instance int 32 Time. In. Seconds(int 32 hours) cil managed { CIL-Code der veränderten Methode Time. In. Seconds(int 32 hours); // Code size 20 (0 x 14) . maxstack 2. locals init ([0] int 32 CS$00000003$0000) IL_0000: ldarg. 0 IL_0001: ldc. i 4. s 33 IL_0003: stfld int 32 Demo. Application 2. Class 1/Time: : h IL_0008: ldarg. 1 IL_0009: ldc. i 4 0 xe 10 IL_000 e: mul this – Zeiger = ldarg. 0 IL_000 f: stloc. 0 IL_0010: br. s IL_0012: ldloc. 0 IL_0013: ret } // end of method Time: : Time. In. Seconds

Arrays newarray etype create a zero-based, one-dimensional array . . . , num. Elements

Arrays newarray etype create a zero-based, one-dimensional array . . . , num. Elements . . . , obj Create a new array with elements of type etype

Arrays ldelem. * array load an element of an stelem. * array store an

Arrays ldelem. * array load an element of an stelem. * array store an element of an . . . , array, index . . . , value . . . , array, index, value . . . Lädt Element (vom Wert value) mit Index im Arrays array auf den Stack Speichert im Array an der Stelle index den Wert value

ldelem. * / stelem. * int x; int [] Integer. Array = new int

ldelem. * / stelem. * int x; int [] Integer. Array = new int [3]; . maxstack 3. locals init ([0] int 32 x, Integer. Array[1] = 4; x = 99 + Integer. Array[1]; [1] int 32[] Integer. Array) IL_0000: ldc. i 4. 3 IL_0001: newarr [mscorlib]System. Int 32 IL_0006: stloc. 1 IL_0007: ldloc. 1 IL_0008: ldc. i 4. 1 IL_0009: ldc. i 4. 4 IL_000 a: stelem. i 4 IL_000 b: ldc. i 4. s 99 IL_000 d: ldloc. 1 IL_000 e: ldc. i 4. 2 IL_000 f: ldelem. i 4 IL_0010: add IL_0011: stloc. 0 IL_0012: ret

ldelem. * / stelem. * Klassendefinition: // Code size 29 (0 x 1 d)

ldelem. * / stelem. * Klassendefinition: // Code size 29 (0 x 1 d) . maxstack 3 public class Haus . locals init ([0] class Demo. Application 2. Class 1/Haus[] Haus. Array) { IL_0000: ldc. i 4. 3 public int Bewohner; } IL_0001: newarr Demo. Application 2. Class 1/Haus IL_0006: stloc. 0 IL_0007: ldloc. 0 Programmcode: IL_0008: ldc. i 4. 2 IL_0009: newobj instance void Demo. Application 2. Class 1/Haus: : . ctor() Haus [] Haus. Array = new Haus [3]; IL_000 e: stelem. ref Haus. Array[2] = new Haus(); IL_000 f: ldloc. 0 IL_0010: ldc. i 4. 2 Haus. Array[2]. Bewohner = 999; IL_0011: ldelem. ref IL_0012: ldc. i 4 0 x 3 e 7 IL_0017: stfld int 32 Demo. Application 2. Class 1/Haus: : Bewohner IL_001 c: ret

Structures – Werttypen Achtung: Eine Struktur (bzw. Enumeration, allgemein Werttyp) liegt nicht auf dem

Structures – Werttypen Achtung: Eine Struktur (bzw. Enumeration, allgemein Werttyp) liegt nicht auf dem Heap, sondern steht am evaluation stack zur Verfügung. Beispiel: struct Point { Hauptprogramm: public int x, y; } Point My. Point = new Point();

Structures – Werttypen. maxstack 1. locals init ([0] valuetype Console. Application 2. Point My.

Structures – Werttypen. maxstack 1. locals init ([0] valuetype Console. Application 2. Point My. Point) IL_0000: ldloca. s My. Point IL_0002: initobj Console. Application 2. Point IL_0008: ret Hauptprogramm: Point My. Point = new Point(); initobj class. Tok type initialize a value . . . , addr. Of. Val. Obj . . . , Initialisiert alle Felder entsprechend auf null oder 0

Structures – Werttypen statische, globale Methode: public static void Init. Point(Point a) Hauptprogramm: {

Structures – Werttypen statische, globale Methode: public static void Init. Point(Point a) Hauptprogramm: { a. x = 10; Point My. Point = new Point(); a. y = 20; Init. Point(My. Point); }. maxstack 1. locals init ([0] valuetype Console. Application 2. Point My. Point) IL_0000: ldloca. s My. Point IL_0002: initobj Console. Application 2. Point IL_0008: ldloc. 0 IL_0009: call void Console. Application 2. Class 1: : Init. Point(valuetype Console. Application 2. Point) IL_000 e: ret

Structures – Werttypen public static void Init. Point(Point a) { a. x = 10;

Structures – Werttypen public static void Init. Point(Point a) { a. x = 10; a. y = 20; } Methode Init. Point (Point a) im CIL-Code. maxstack 2 IL_0000: ldarga. s a IL_0002: ldc. i 4. s 10 IL_0004: stfld int 32 Console. Application 2. Point: : x IL_0009: ldarga. s a IL_000 b: ldc. i 4. s 20 IL_000 d: stfld IL_0012: ret int 32 Console. Application 2. Point: : y

Boxing – Unboxing object obj = 3; // Boxing int x = (int) obj;

Boxing – Unboxing object obj = 3; // Boxing int x = (int) obj; // Unboxing . maxstack 1. locals init ([0] object obj, [1] int 32 x) box val. Type. Tok convert value type to object reference. . . , value. Type . . . , obj unbox value. Type convert boxed type into its raw form. . . , obj . . . , value. Type. Ptr Boxing: IL_0000: ldc. i 4. 3 IL_0001: box [mscorlib]System. Int 32 IL_0006: stloc. 0 Unboxing: IL_0007: ldloc. 0 IL_0008: unbox IL_000 d: ldind. i 4 IL_000 e: stloc. 1 IL_000 f: ret [mscorlib]System. Int 32

Boxing – Unboxing. maxstack 1. locals init ([0] object obj, [1] int 32 x)

Boxing – Unboxing. maxstack 1. locals init ([0] object obj, [1] int 32 x) Boxing: IL_0000: ldc. i 4. 3 IL_0001: box [mscorlib]System. Int 32 IL_0006: stloc. 0 Unboxing: IL_0007: ldloc. 0 IL_0008: unbox IL_000 d: ldind. i 4 IL_000 e: stloc. 1 IL_000 f: ret [mscorlib]System. Int 32 box val. Type. Tok object reference convert value type to . . . , value. Type . . . , obj unbox value. Type its raw form convert boxed type into . . . , obj . . . , value. Type. Ptr

Delegate(s) . maxstack 3. locals init ([0] class Demo. Application 2. Class 1/Reference refer,

Delegate(s) . maxstack 3. locals init ([0] class Demo. Application 2. Class 1/Reference refer, Statische, globale Methode: [1] int 32 a, public static void Demo. Reference(ref int a, ref int b) [2] int 32 b) { IL_0000: ldnull int x; IL_0001: ldftn void Demo. Application 2. Class 1: : Demo. Reference(int 32&, a = 90; x = b; } int 32&) IL_0007: newobj instance void Demo. Application 2. Class 1/Reference: : . ctor(object, native int) Deklaration des Methodentyps = Delegate: delegate void Reference(ref int a, ref int b); IL_000 c: stloc. 0 IL_000 d: ldc. i 4. s 20 IL_000 f: stloc. 1 IL_0010: ldc. i 4. s 30 Hauptprogramm: IL_0012: stloc. 2 Reference refer; IL_0013: ldloc. 0 refer = new Reference(Demo. Reference); IL_0014: ldloca. s a ldftn method load method pointer … …, ftn pusht einen Zeiger auf eine Methode referenziert von method auf den Stack; Wird zur Konstruktion eines Delegates verwendet. IL_0016: ldloca. s b int a = 20, b = 30; refer(ref a, ref b); IL_0018: callvirt instance void Demo. Application 2. Class 1/Reference: : Invoke(int 32&, int 32&) IL_001 d: ret

Operationen add numeric values multiply values . . . , value 1, value 2

Operationen add numeric values multiply values . . . , value 1, value 2 . . . result addiert value 1 und value 2 multipliziert value 1 mit value 2 sub div subtract numeric values divide values . . . , value 1, value 2 . . . result subtrahiert value 2 von value 1 dividiert value 1 durch value 2

Operationen negate . . . , value . . . , result Gibt das

Operationen negate . . . , value . . . , result Gibt das 2 er Komplement für Ganzzahl- und Fliesskommatypen zurück. rem compute remainder . . . , value 1, value 2 . . . result ergibt den Rest von value 1 dividiert durch value 2 Weitere Operatoren: add. ovf, add. ovf. un add [un]signed integer values with overflow check div. un divide interger values, unsigned mul. ovf, mul. ovf. un multiply integer values with overflow check rem. un compute integer remainder, unsigned sub. ovf, sub. ovf. un subtract integer values, checking for overflow

Shift-Operationen shl shift integer left (arithmetic shift) . . . , value, shift. Amount

Shift-Operationen shl shift integer left (arithmetic shift) . . . , value, shift. Amount . . . result shiftet value um shift. Amount Stellen nach links shr shift integer right (arithmetic shift) . . . , value, shift. Amount . . . result shiftet value um shift. Amount Stellen nach rechts shr. un shift integer right, unsigned (logical shift) . . . , value, shift. Amount . . . result shiftet value um shift. Amount Stellen nach rechts

Typkonvertierung auf dem Stack conv. <to type> data conversion . . . , value

Typkonvertierung auf dem Stack conv. <to type> data conversion . . . , value . . . result Konvertiert value in den (im Opcode) spezifizierten Typ <to type> ist i 1, i 2, i 4, i 8, r 4, r 8, u 1, u 2, u 4, u 8, i, u, r. un außerdem: conv. ovf. <to type> data conversion with overflow detection <to type> ist i 1, i 2, i 4, i 8, u 1, u 2, u 4, u 8, i, u conv. ovf. <to type>. un unsigned data conversion with overflow detection <to type> ist i 1, i 2, i 4, i 8, u 1, u 2, u 4, u 8, i, u

Bitweise Operationen and bitwise AND . . . , value 1, value 2 .

Bitweise Operationen and bitwise AND . . . , value 1, value 2 . . . result bitweises AND zweier ganzzahliger Werte, lässt ganzzahliges Resultat zurück or bitwise OR . . . , value 1, value 2 . . . result bitweises OR zweier ganzzahliger Werte, lässt ganzzahliges Resultat zurück xor bitwise XOR . . . , value 1, value 2 . . . result bitweises OR zweier ganzzahliger Werte, lässt ganzzahliges Resultat zurück not bitwise complement . . . , value . . . result bitweises Komplement von value, result ist vom selben Typ wie value

Spezielle Instruktionen duplicate the top value of the stack . . . , value,

Spezielle Instruktionen duplicate the top value of the stack . . . , value, value dupliziert das oberste Element am Stack pop a value from the stack . . . , value . . . entfernt das oberste Element vom Stack nop Do nothing . . . macht gar nichts

Boolsche Operationen (1) ceq compare equal . . . , value 1, value 2

Boolsche Operationen (1) ceq compare equal . . . , value 1, value 2 . . . result legt 1 auf den Stack, falls value 1 gleich value 2, sonst 0 cgt compare greater than . . . , value 1, value 2 . . . result legt 1 auf den Stack, falls value 1 größer value 2, 0 sonst clt compare less than . . . , value 1, value 2 . . . result legt 1 auf den Stack, falls value 1 kleiner value 2, sonst 0 cgt. un target compare greater than, unsigned or unordered clt. un target compare less than, unsigned or unordered

Boolsche Operationen (2) Weitere Identitäten: Äquivalente Instruktionssequenz: a, b: (a b) = ¬(a b)

Boolsche Operationen (2) Weitere Identitäten: Äquivalente Instruktionssequenz: a, b: (a b) = ¬(a b) ceq; ldc. 1; xor a, b: (a b) = ¬(a b) cgt; ldc. 1; xor a, b: (a b) = ¬(a b) clt; ldc. 1; xor

Boolsche Operation – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a,

Boolsche Operation – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a, int a = 10; [1] int 32 b, int b = 20; [2] bool c) IL_0000: ldc. i 4. s 10 bool c = ( a != b ); IL_0002: stloc. 0 IL_0003: ldc. i 4. s 20 IL_0005: stloc. 1 IL_0006: ldloc. 0 IL_0007: ldloc. 1 IL_0008: ceq IL_000 a: ldc. i 4. 0 IL_000 b: ceq IL_000 d: stloc. 2 IL_000 e: ret

Flow Control – Branch Instructions (1) br target unconditional branch . . . ,

Flow Control – Branch Instructions (1) br target unconditional branch . . . , . . . Kontrollfluss springt zu target brfalse target branch on null, false or zero . . . , value . . . Kontrollfluss springt zu target, falls value false, 0 oder null ist. brtrue target branch on non-false or non-null . . . , value . . . Kontrollfluss springt zu target, falls value nichtfalse, ungleich 0 oder nichtnull ist.

Flow Control – Branch Instructions (2) beq target branch on equal. . . ,

Flow Control – Branch Instructions (2) beq target branch on equal. . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 gleich value 2 ist. bge target branch on greater than or equal to . . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 größer oder gleich value 2 ist. bgt target branch on greater than . . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 größer value 2 ist. bge. un target branch on greater than or equal to, unsigned or unordered bgt. un target branch on greater than, unsigned or unordered

Flow Control – Branch Instructions (3) ble target branch on less than or equal

Flow Control – Branch Instructions (3) ble target branch on less than or equal to . . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 kleiner oder gleich value 2 ist. blt target branch on less than . . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 kleiner value 2 ist. bne. un target branch on not equal or unordered . . . , value 1, value 2 . . . Kontrollfluss springt zu target, falls value 1 ungleich value 2 ist. ble. un target branch on greater than or equal to, unsigned or unordered blt. un target branch on greater than, unsigned or unordered

Flow Control – Beispiel Codestück: . maxstack 1. locals init ([0] bool eins, bool

Flow Control – Beispiel Codestück: . maxstack 1. locals init ([0] bool eins, bool eins = false; bool zwei = true; [1] bool zwei) IL_0000: ldc. i 4. 0 IL_0001: stloc. 0 if (eins || zwei) IL_0002: ldc. i 4. 1 { IL_0003: stloc. 1 Console. Write. Line("if-Schleife betreten"); } IL_0004: ldloc. 0 IL_0005: brtrue. s IL_000 a IL_0007: ldloc. 1 IL_0008: brfalse. s IL_0014 IL_000 a: ldstr "if-Schleife betreten" IL_000 f: call void [mscorlib]System. Console: : Write. Line(string) IL_0014: ret

Flow Control – Beispiel Codestück: . maxstack 1. locals init ([0] bool eins, bool

Flow Control – Beispiel Codestück: . maxstack 1. locals init ([0] bool eins, bool eins = false; bool zwei = true; [1] bool zwei) IL_0000: ldc. i 4. 0 IL_0001: stloc. 0 if (eins && zwei) IL_0002: ldc. i 4. 1 { IL_0003: stloc. 1 Console. Write. Line("if-Schleife betreten"); } IL_0004: ldloc. 0 IL_0005: brfalse. s IL_0014 IL_0007: ldloc. 1 IL_0008: brfalse. s IL_0014 IL_000 a: ldstr "if-Schleife betreten" IL_000 f: call void [mscorlib]System. Console: : Write. Line(string) IL_0014: ret

Flow Control – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a,

Flow Control – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a, int a = 10; [1] int 32 b) int b = 20; IL_0000: ldc. i 4. s 10 IL_0002: stloc. 0 while (b > a) IL_0003: ldc. i 4. s 20 { IL_0005: stloc. 1 b--; } IL_0006: br. s IL_000 c IL_0008: ldloc. 1 IL_0009: ldc. i 4. 1 IL_000 a: sub IL_000 b: stloc. 1 IL_000 c: ldloc. 1 IL_000 d: ldloc. 0 IL_000 e: bgt. s IL_0010: ret IL_0008

Flow Control – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a,

Flow Control – Beispiel Codestück: . maxstack 2. locals init ([0] int 32 a, int a = 10; [1] int 32 b) int b = 20; IL_0000: ldc. i 4. s 10 IL_0002: stloc. 0 do IL_0003: ldc. i 4. s 20 { IL_0005: stloc. 1 b--; } while (b > a); IL_0006: ldloc. 1 IL_0007: ldc. i 4. 1 IL_0008: sub IL_0009: stloc. 1 IL_000 a: ldloc. 1 IL_000 b: ldloc. 0 IL_000 c: bgt. s IL_000 e: ret IL_0006

Literatur Vollständige Spezifikation der CIL in: ECMA-335, CLI Partition III: CIL Instruction Set (siehe

Literatur Vollständige Spezifikation der CIL in: ECMA-335, CLI Partition III: CIL Instruction Set (siehe www. emca-international. org) John Gough: Compiling for the. NET Common Language Runtime Prentice Hall, 2002 Kapitel 2 (bzw. 3 & 4), sowie Kapitel 8 & 9 Kevin Burton: . NET Common Language Runtime Unleashed Sams Publishing, 2002 Kapitel 5 Ergänzender Überblick und Einführung: W. Beer, D. Birngruber, H. Mössenböck, A. Wöß: Die. NET-Technologie, dpunkt. verlag 2002 Kapitel 3

Exception handling instructions (1) try { . maxstack 3. locals init ([0] int 32[]

Exception handling instructions (1) try { . maxstack 3. locals init ([0] int 32[] a, [1] class Demo. Application 3. Class 1/My. Exception e, [2] class [mscorlib]System. Exception V_2). . try { IL_0000: ldc. i 4. 3 IL_0001: newarr int [] a = new int[3]; a[1] = 6 + 7; [mscorlib]System. Int 32 IL_0006: stloc. 0 IL_0007: ldloc. 0 if (a[1] > 10) { IL_0008: ldc. i 4. 1 throw new My. Exception(); } IL_0009: ldc. i 4. s 13 IL_000 b: stelem. i 4 } IL_000 c: ldloc. 0 IL_000 d: ldc. i 4. 1 IL_000 e: ldelem. i 4 IL_000 f: ldc. i 4. s 10 throw an exception . . . , object (? ) object ist eine Objektreferenz (Typ o) IL_0011: ble. s IL_0019 IL_0013: newobj instance void Demo. Application 3. Class 1/My. Exception: : . ctor() IL_0018: throw IL_0019: leave. s } // end. try IL_0036

Exception handling instructions (2) catch (My. Exception e) { Console. Write. Line("My. Exception catch

Exception handling instructions (2) catch (My. Exception e) { Console. Write. Line("My. Exception catch Demo. Application 3. Class 1/My. Exception { occurred!"); } IL_001 b: stloc. 1 IL_001 c: ldstr "My. Exception occurred!" catch (Exception e) { Console. Write. Line(e. To. String()); } IL_0021: call void [mscorlib]System. Console: : Write. Line(string) IL_0026: leave. s IL_0036 } // end handler catch [mscorlib]System. Exception { IL_0028: stloc. 2 IL_0029: ldloc. 2 IL_002 a: callvirt instance string [mscorlib]System. Exception: : To. String() IL_002 f: call IL_0034: leave. s void [mscorlib]System. Console: : Write. Line(string) IL_0036 } // end handler IL_0036: leave. s } // end. try IL_0043

Exception handling instructions (3) finally { Console. Write. Line("Finally-Block reached!"); } finally { IL_0038:

Exception handling instructions (3) finally { Console. Write. Line("Finally-Block reached!"); } finally { IL_0038: ldstr "Finally-Block reached!" IL_003 d: call void [mscorlib]System. Console: : Write. Line(string) IL_0042: endfinally } // end handler IL_0043: ret