Freigeben über


Kompilieren von MSIL in systemeigenen Code

Aktualisiert: November 2007

Bevor Microsoft Intermediate Language (MSIL) ausgeführt werden kann, muss sie in der Common Language Runtime in systemeigenen Code kompiliert werden, und zwar in der Common Language Runtime für die Architektur des Zielcomputers. .NET Framework bietet zwei Möglichkeiten zum Ausführen dieser Konvertierung:

Kompilierung mit dem JIT (Just-In-Time)-Compiler

Bei der JIT-Kompilierung wird MSIL zur Anwendungslaufzeit auf Abruf in systemeigenen Code konvertiert, sobald der Inhalt einer Assembly geladen und ausgeführt wird. Da die Common Language Runtime für jede unterstützte CPU-Architektur einen JIT-Compiler bereitstellt, können Entwickler eine Reihe von MSIL-Assemblys erstellen, die JIT-kompiliert und auf unterschiedlichen Computern mit abweichender Architektur ausgeführt werden können. Verwalteter Code kann jedoch unter einem bestimmten Betriebssystem nur dann ausgeführt werden, wenn dieser plattformspezifische, systemeigene APIs oder eine plattformspezifische Klassenbibliothek aufruft.

Bei der JIT-Kompilierung wird berücksichtigt, dass ein Teil des Codes bei der Ausführung möglicherweise nicht aufgerufen wird. Statt für das Konvertieren der gesamten MSIL einer PE-Datei (Portable Executable) in systemeigenen Code Zeit und Speicherplatz zu beanspruchen, wird die MSIL während der Ausführung nach Bedarf konvertiert. Der resultierende systemeigene Code wird im Arbeitsspeicher gespeichert, sodass bei nachfolgenden Aufrufen im Kontext dieses Prozesses darauf zugegriffen werden kann. Das Ladeprogramm erstellt einen Stub und fügt diesen an jede Methode des Typs an, wenn dieser Typ geladen und initialisiert wird. Beim ersten Aufruf der Methode übergibt der Stub die Steuerung an den JIT-Compiler, der die MSIL für diese Methode in systemeigenen Code konvertiert und den Stub so ändert, dass er direkt auf den generierten systemeigenen Code verweist. Nachfolgende Aufrufe der JIT-kompilierten Methode setzen deshalb direkt beim systemeigenen Code an.

Codegenerierung bei der Installation mithilfe von NGen.exe

Da der JIT-Compiler die MSIL einer Assembly in systemeigenen Code konvertiert, wenn einzelne in dieser Assembly definierte Methoden aufgerufen werden, treten zur Laufzeit unweigerlich Leistungseinbußen auf. In den meisten Fällen sind diese Leistungseinbußen hinnehmbar. Eine größere Rolle spielt jedoch, dass der vom JIT-Compiler generierte Code an den Prozess gebunden ist, durch den die Kompilierung ausgelöst wurde. Er kann also nicht für mehrere Prozesse verwendet werden. Damit der generierte Code für mehrere Aufrufe einer Anwendung oder mehrere Prozesse verwendet werden kann, die eine Gruppe von Assemblys gemeinsam nutzen, unterstützt die Common Language Runtime einen vorzeitigen Kompilierungsmodus. Dieser vorzeitige Kompilierungsmodus verwendet den Native Image Generator (Ngen.exe), um MSIL-Assemblys ähnlich wie der JIT-Compiler in systemeigenen Code zu konvertieren. Die Ausführung von Ngen.exe unterscheidet sich jedoch auf drei Weisen von der Ausführung des JIT-Compilers:

  • Die Konvertierung von MSIL in systemeigenem Code wird vor und nicht während der Ausführung der Anwendung durchgeführt.

  • Es werden jeweils ganze Assemblys und nicht einzelne Methoden kompiliert.

  • Der generierte Code im Cache für systemeigene Abbilder wird als Datei auf dem Datenträger beibehalten.

Codeüberprüfung

Beim Kompilieren der MSIL in systemeigenen Code muss der MSIL-Code eine Überprüfung durchlaufen. Dies ist nicht erforderlich, wenn der Administrator Sicherheitsrichtlinien erstellt hat, mit denen die Überprüfung des Codes umgangen werden kann. MSIL und Metadaten werden daraufhin überprüft, ob der Code typsicher ist, d. h., ob er nur auf Speicherorte zugreift, für die ihm der Zugriff gewährt ist. Typsicherheit ermöglicht das Isolieren von Objekten voneinander und trägt damit zum Schutz dieser Objekte vor unabsichtlicher oder böswilliger Beschädigung bei. Typsicherheit bietet außerdem die Gewissheit, dass Sicherheitsbeschränkung für Code zuverlässig erzwungen werden können.

Für die Laufzeit ist erforderlich, dass die folgenden Aussagen auf überprüfbar typsicheren Code zutreffen:

  • Ein Verweis auf einen Typ ist vollständig kompatibel mit dem Typ, auf den verwiesen wird.

  • Für ein Objekt werden nur angemessen definierte Operationen aufgerufen.

  • Identitäten sind, was sie von sich behaupten.

Während der Überprüfung von MSIL-Code wird versucht sicherzustellen, dass dieser nur über ordnungsgemäß definierte Typen auf Speicherorte zugreifen und Methoden aufrufen kann. Code muss z. B. die Überlastung von Speicherorten beim Zugriff auf Felder eines Objekts verhindern. Code wird außerdem daraufhin überprüft, ob die MSIL fehlerfrei generiert wurde, da fehlerhafte MSIL zu einer Verletzung der Regeln für die Typsicherheit führen kann. Bei der Überprüfung wird ein genau definierter Abschnitt typsicheren Codes übergeben, und es wird ausschließlich Code übergeben, der typsicher ist. Aufgrund einiger Einschränkungen während der Überprüfung ist es jedoch möglich, dass ein Teil des typsicheren Codes die Überprüfung nicht besteht. Zudem kann in einigen Sprachen kein überprüfbar typsicherer Code erstellt werden. Wenn die Sicherheitsrichtlinien typsicheren Code erfordern, aber der Code die Überprüfung nicht besteht, wird bei der Ausführung des Codes eine Ausnahme ausgelöst.

Siehe auch

Konzepte

Der verwaltete Ausführungsprozess