it-swarm.com.de

Warum müssen VMs "Stack-Maschinen" oder "Register-Maschinen" usw. sein?

(Dies ist eine extrem neue Frage).

Ich habe ein wenig über virtuelle Maschinen gelernt.

Es stellt sich heraus, dass viele von ihnen sehr ähnlich wie physische oder theoretische Computer konzipiert sind.

Ich habe gelesen, dass die JVM zum Beispiel eine 'Stack-Maschine' ist. Das bedeutet (und korrigiert mich, wenn ich falsch liege), dass es seinen gesamten 'temporären Speicher' auf einem Stapel speichert und Operationen auf diesem Stapel für alle seine Opcodes ausführt.

Zum Beispiel der Quellcode 2 + 3 wird in folgenden Bytecode übersetzt:

Push 2
Push 3
add

Meine Frage lautet:

JVMs werden wahrscheinlich mit C/C++ und dergleichen geschrieben. Wenn ja, warum führt die JVM den folgenden C-Code nicht aus: 2 + 3 ..? Ich meine, warum braucht es einen Stack oder in anderen VMs-Registern - wie in einem physischen Computer?

Die zugrunde liegende physische CPU kümmert sich um all dies. Warum nicht VM-Writer führen den interpretierten Bytecode einfach mit 'üblichen' Anweisungen in der Sprache aus, mit der VM programmiert ist)?

Warum müssen VMs Hardware emulieren, wenn die eigentliche Hardware dies bereits für uns erledigt?

Wieder sehr neue Fragen. Danke für Ihre Hilfe

48
Aviv Cohn

Eine Maschine, ob virtuell oder nicht, benötigt ein Berechnungsmodell , das beschreibt, wie die Berechnung auf ihr ausgeführt wird. Per Definition implementiert es, sobald es berechnet, ein Berechnungsmodell. Die Frage ist dann: Welches Modell sollten wir für unsere VM wählen? Physische Maschinen werden durch das eingeschränkt, was in Hardware effektiv und effizient durchgeführt werden kann. Wie Sie jedoch bemerken, unterliegen virtuelle Maschinen keinen solchen Einschränkungen. Sie werden in Software unter Verwendung beliebig hoher Sprachen definiert.

Tatsächlich gibt es virtuelle Maschinen, die, wie Sie beschreiben, auf hohem Niveau sind. Sie werden Programmiersprachen genannt. Der C-Standard widmet beispielsweise den Großteil seiner Seiten der Definition eines Modells für die sogenannte "abstrakte C-Maschine", das beschreibt, wie sich C-Programme verhalten, und im weiteren Sinne (als ob-Regel), wie ein konformer C-Compiler (oder Interpreter) sollte Verhalten.

Natürlich nennen wir das normalerweise keine virtuelle Maschine. Ein VM) bedeutet normalerweise etwas niedrigeres, näher an der Hardware, das nicht direkt programmiert werden soll und effizient ausgeführt werden soll. Diese Auswahlverzerrung bedeutet, dass etwas auf hoher Ebene zusammengesetzt werden kann Code (wie von Ihnen beschrieben) wird nicht als VM ) betrachtet, da Code auf hoher Ebene ausführt.

Um auf den Punkt zu kommen, gibt es hier einige Gründe, ein VM (wie in, etwas, auf das ein Bytecode-Compiler abzielt) auf Registerbasis oder dergleichen zu erstellen. Stapel- und Registermaschinen sind äußerst einfach Es gibt eine Folge von Anweisungen, einen Status und eine Semantik für jede Anweisung (eine Funktion Status -> Status). Keine komplexen Baumreduktionen, keine Operatorpriorität. Das Parsen, Analysieren und Ausführen ist sehr einfach, da es sich um eine minimale Sprache handelt (syntaktisch) Zucker wird zusammengestellt) und ist so konzipiert, dass er eher maschinell als menschlich gelesen werden kann.

Im Gegensatz dazu ist das Parsen selbst der einfachsten C-ähnlichen Sprachen ziemlich schwierig, und die Ausführung erfordert nicht-lokale Analysen wie das Überprüfen und Weitergeben von Typen, das Auflösen von Überladungen, das Verwalten einer Symboltabelle und das Auflösen von string Bezeichner, die linearen Text in einen vorrangigen AST verwandeln, und so weiter. Es baut auf Konzepten auf, die für den Menschen selbstverständlich sind, aber von Maschinen sorgfältig rückentwickelt werden müssen.

JVM-Bytecode wird beispielsweise von javac ausgegeben. Es muss praktisch nie von Menschen gelesen oder geschrieben werden, daher ist es selbstverständlich, es auf den Verbrauch durch Maschinen auszurichten. Wenn Sie es für Menschen optimiert hätten, würde die JVM bei jedem Start den Code lesen, analysieren, analysieren und ihn dann in eine Zwischendarstellung umwandeln, die ohnehin einem solchen vereinfachten Maschinenmodell ähnelt . Könnte auch den mittleren Mann ausschneiden.

51
user7043

Diese Antwort konzentriert sich auf die JVM, gilt jedoch für jede VM.

Warum müssen VMs Hardware emulieren, wenn die eigentliche Hardware dies bereits für uns erledigt?

Sie tun es nicht, aber es macht die VM viel einfacher und portabler: A VM, die Hardware emuliert, kann dasselbe Rechenmodell verwenden wie jede Hardware-CPU.

Insbesondere die JVM wurde mit Blick auf die Portabilität entwickelt. Tatsächlich wurde sie so gebaut, dass sie sogar in Hardware implementiert werden kann (es mag heute kaum zu glauben sein, aber das Origin of Java befand sich in der eingebetteten Welt - speziell Controller für interaktives Fernsehen).

Wenn Sie ein solches Ziel haben, ist es wünschenswert, dass die VM so nahe wie möglich an einer physischen Maschine arbeitet, da die Übersetzung in tatsächlichen Maschinencode einfacher und damit schneller wird. Sobald Sie die Opcodes haben Theoretisch müssen Sie von der VM lediglich in Opcodes der CPU übersetzen, auf der das Programm tatsächlich ausgeführt wird. In der Praxis ist dies nicht ganz so einfach.

Ich meine, warum braucht es einen Stack oder in anderen VMs-Registern - wie in einem physischen Computer?

Die Verwendung eines stapelbasierten Modells einer virtuellen Maschine hat den Vorteil, dass es leicht sowohl auf Register- als auch auf Stapelmaschinen übertragen werden kann, während das Gegenteil nicht unbedingt der Fall ist. Ein registergestütztes VM müsste Annahmen über die Anzahl der Register, die Größe der Register usw. treffen. Bei einer Stapelmaschine sind solche Annahmen nicht erforderlich.

Die zugrunde liegende physische CPU kümmert sich um all dies. Warum nicht VM-Writer führen den interpretierten Bytecode einfach mit 'üblichen' Anweisungen in der Sprache aus, mit der VM programmiert ist)?

Genau das tun solche VMs, sie interpretieren Bytecode. Sogar die JVM tut dies tatsächlich, zumindest bevor die JIT (Just-in-Time) startet: Sie interpretiert die Bytecodes und führt die Anweisungen in der Sprache aus, in der die JVM geschrieben wurde (normalerweise C oder C++, aber es ist sogar eine geschrieben) in JavaScript Doppio ). Beachten Sie jedoch, dass selbst solche Anweisungen von einem Compiler in Maschinencode übersetzt wurden und tatsächlich sehr ähnlich aussehen wie das, was der Java - Compiler erzeugt - nämlich, dass sie Register und den Stapel verwenden, um ihre Arbeit auszuführen. Beachten Sie, dass die Verwendung von "interpretierten" und "kompilierten" Sprachen an dieser Stelle etwas verschwommen wird.

20
miraculixx

Warum müssen VMs "Stack-Maschinen" oder "Register-Maschinen" usw. sein?

Sie nicht. Wenn Sie eine virtuelle Maschine benötigen, kann dies alles sein.

Die vorhandenen virtuellen Maschinen sind als Lösungen für folgende Situationen erschienen: Eine wirklich brillante Idee ist mir in den Sinn gekommen, ich habe eine neue Programmiersprache erfunden! Aber ich muss Code generieren. (Was für eine langweilige Aufgabe!) Aber Ich möchte keinen i8086-Code generieren, weil er hässlich ist, und ich möchte keinen 68k-Code generieren, weil alle anderen Intel verwenden. Es gibt auch VAX, aber ich habe keinen VAX, weder einen Computer noch ein VAX-Buch Ich werde Code für einen Prozessor generieren, der physisch nicht existiert, und diesen Prozessor in Software implementieren. Die Spezifikation von VM wird ein Kapitel in meiner Arbeit bilden. Theoretisch wird es möglich sein, zu kompilieren es zu nativem Code eines Prozessors, aber das werde ich nicht sein.

Andererseits wird die Notation wie "2 + 3" in absehbarer Zeit wahrscheinlich nicht von VMs verwendet, da dies viele Transformationen erfordert, bevor etwas ausgeführt werden kann.

11