Was ist der Zweck eines Stapels? Warum brauchen wir es?
So, ich bin lernen MSIL jetzt zu lernen, zu Debuggen meiner C# .NET-Anwendungen.
Ich habe mich immer gefragt: was ist der Zweck der stack?
Nur, um meine Frage im Kontext:
Warum gibt es eine übertragung aus dem Speicher auf den stack oder "laden?"
Auf der anderen Seite, warum gibt es einen transfer vom stack-Speicher oder auf "speichern"?
Warum nicht einfach haben, Sie alle in den Speicher?
- Ist es, weil es schneller?
- Ist es, weil es RAM?
- Für Effizienz?
Ich versuche zu begreifen, um mir zu helfen zu verstehen, CIL codes viel tiefer.
InformationsquelleAutor der Frage Jan Carlo Viray | 2011-10-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
UPDATE: ich mochte diese Frage, so sehr ich es gemacht das Thema von meinem blog am 18. November 2011. Vielen Dank für die tolle Frage!
Ich nehme an, du meinst die evaluation stack der MSIL-Sprache, und nicht die tatsächlichen pro-thread-stack zur Laufzeit.
MSIL ist ein "virtual machine" - Sprache. Compiler der C# - compiler erzeugen CILund dann zur Laufzeit einen anderen compiler aufgerufen, der JIT - (Just In Time) compiler wandelt den IL in Maschinensprache-Anweisungen, die ausgeführt werden können.
Also lassen Sie uns zunächst die Antwort auf die Frage "warum haben MSIL überhaupt?" Warum nicht einfach haben, den C# - compiler schreiben, die Maschinen-code?
Weil es billigeres zu tun auf diese Weise. Angenommen, wir habe es nicht so; angenommen, jede Sprache hat Ihre eigenen Computer-code-generator. Sie haben zwanzig verschiedene Sprachen: C#, JScript .NETVisual Basic, IronPythonF#... Und angenommen, Sie haben zehn verschiedene Prozessoren. Wie viele code-Generatoren haben Sie zu schreiben? 20 x 10 = 200 code-Generatoren. Das ist eine Menge Arbeit. Nehmen wir nun an, die Sie hinzufügen möchten, einen neuen Prozessor. Schreiben Sie die code-generator für die es zwanzig mal, eine für jede Sprache.
Darüber hinaus ist es schwierig und gefährlich die Arbeit. Schreiben von effizienten code-Generatoren für chips, dass Sie nicht ein Experte ist ein harter job! Compiler-Designer sind Experten für die semantische Analyse der Sprache, nicht auf effiziente registrieren Vergabe von neuen chip-sets.
Nun nehmen wir an, wir tun es auch die CIL Weg. Wie viele CIL-Generatoren haben Sie zu schreiben? Eine pro Sprache. Wie viele JIT-Compiler haben Sie zu schreiben? Eine pro Prozessor. Insgesamt: 20 + 10 = 30 code-Generatoren. Außerdem, die Sprache-zu-CIL-generator ist einfach zu schreiben, weil CIL ist eine einfache Sprache, und die CIL-to-machine-code-generator ist auch leicht zu schreiben, weil CIL ist eine einfache Sprache. Wir loszuwerden, alle die Feinheiten von C# und VB und so weiter und "untere" alles auf eine einfache Sprache, die leicht zu schreiben jitter.
Dass eine intermediate language, senkt die Kosten für die Herstellung einer neuen Sprache compiler dramatisch. Es senkt auch die Kosten für einen neuen chip drastisch. Sie benötigen Unterstützung für einen neuen chip finden Sie einige Experten auf diesem chip haben und Sie schreiben Sie eine CIL-jitter und Sie fertig sind; Sie unterstützen dann all jene Sprachen, die auf Ihren chip.
OK, also wir haben begründet, warum wir MSIL; denn eine intermediate-language-Kosten senkt. Warum ist dann die Sprache ein "stack machine"?
Weil stack-Maschinen sind im Prinzip sehr einfach, die Sprache mit compiler-Autoren zu beschäftigen. Stacks sind eine einfache, leicht verständliche Mechanismus für die Beschreibung von Berechnungen. Stack-Maschinen sind auch konzeptionell sehr einfach für den JIT-compiler-Autoren zu beschäftigen. Mit einem stack ist eine vereinfachende Abstraktion, und daher wieder es senkt unsere Kosten.
Fragen Sie "warum haben Sie einen stack überhaupt?" Warum nicht einfach alles direkt out-of-memory? Nun, lassen Sie uns darüber nachdenken. Angenommen, Sie möchten zu generieren CIL-code für:
Nehmen wir an, wir haben die Konvention, dass "hinzufügen", "anrufen", "speichern" und so weiter, nehmen Sie immer Ihre Argumente aus dem Stapel und legte deren Ergebnis (falls es eines gibt) auf den stack. Generieren CIL-code für die C# wir nur sagen, so etwas wie:
Nun nehmen wir an, wir haben es ohne einen Stapel. Wir werden es tun, Ihren Weg, wo jeder opcode nimmt die Adressen der Operanden und an welche Adresse er speichert sein Ergebnis:
Sehen Sie, wie das geht? Unser code ist immer riesige denn wir haben ausdrücklich weisen die vorübergehende Lagerung die normalerweise von der Konvention gehen Sie einfach auf den Stapel. Noch schlimmer, unsere Befehle selbst sind alle immer enorm, weil Sie alle haben jetzt zu nehmen als argument die Adresse, die Sie gehen zu schreiben, deren Ergebnis-in und der Adresse des jeweiligen Operanden. Ein "add" - Befehl, der weiß, dass es geht um zwei Dinge, aus dem Stapel und legen Sie eine Sache, auf ein einzelnes byte. Ein add-Befehl mit zwei Operanden-Adressen und Folge Adresse wird enorm sein.
Verwenden wir die stack-basierte opcodes, weil stapeln lösen das gemeinsame problem. Nämlich: will ich weisen Sie einige temporäre Speicherung, die es verwenden, sehr bald und dann, es loszuwerden schnell, wenn ich fertig bin. Durch die Annahme, dass wir einen Stapel zu unserer Verfügung stehen, können wir die opcodes sehr klein und der code sehr kurz gehalten.
UPDATE: Einige weitere Gedanken
Übrigens, diese Idee zu einer drastischen Senkung der Kosten von (1) definieren einer virtuellen Maschine, (2) schreiben von Compilern, deren Ziel die VM Sprache, und (3) schreiben von Implementierungen der virtuellen Maschine auf einer Vielzahl von hardware -, ist nicht eine neue Idee. Es gar nicht aus mit MSIL, LLVM, Java-bytecode oder jedem anderen modernen Infrastrukturen. Die früheste Umsetzung dieser Strategie, die ich bewusst bin, ist die pcode-Maschine aus dem Jahr 1966.
Der erste, den ich persönlich gehört dieses Konzept wurde als ich erfuhr, wie die Infocom implementors geschafft, Zork läuft auf so vielen unterschiedlichen Maschinen so gut. Sie spezifiziert eine virtuelle Maschine namens Z-Maschine und dann Z-Maschine-Emulatoren für alle hardware, die Sie laufen wollten, Ihre Spiele auf. Dies hatte den zusätzlichen enormen Vorteilen, die Sie umsetzen konnte virtual memory management auf primitiven 8-bit-Systeme, ein Spiel größer sein kann als das würde passen in den Speicher, weil Sie nur Seite den code von der Festplatte, wenn Sie es brauchte und es zu verwerfen, wenn Sie benötigt, um zu laden code.
InformationsquelleAutor der Antwort Eric Lippert
Beachten Sie, dass wenn Sie reden MSIL dann redest du eine Anleitung für eine virtuellen Maschine. Die VM verwendet .NET ist eine stack-basierte virtuelle Maschine. Im Gegensatz zu einer register basierten VM, die Dalvik VM verwendet in Android-Betriebssysteme ist ein Beispiel dafür.
Dem Stapel in der VM ist virtuell, es ist bis zu den interpreter oder just-in-time-compiler zu übersetzen, die VM-Hinweise in tatsächliche code, der läuft auf dem Prozessor. Die in der Falle .NET ist fast immer ein jitter, der MSIL-Befehlssatz wurde entwickelt, um jitted aus der sich gehen. Im Gegensatz zu Java-bytecode zum Beispiel, es hat deutliche Anweisungen für Operationen, die auf bestimmte Datentypen. Was es macht optimiert auszulegen. Ein MSIL-interpreter tatsächlich existiert, obwohl es verwendet wird, in den .NET Micro Framework. Die läuft auf Prozessoren mit sehr begrenzten Ressourcen nicht leisten können, die erforderlichen RAM zum speichern von Maschinen-code.
Den tatsächlichen Computer-code-Modell ist gemischt, mit einem stack und Registern. Eine der großen Aufgaben des JIT-code-Optimierer ist zu kommen mit Möglichkeiten zum speichern von Variablen gehalten werden, die auf dem stack-Register, wodurch erheblich zur Verbesserung der Ausführungsgeschwindigkeit. Ein Dalvik jitter hat das umgekehrte problem.
Die Maschine stack ist sonst eine sehr grundlegende storage-Anlage, die schon im Prozessor-designs für eine sehr lange Zeit. Es hat eine sehr gute Lokalität der Referenz, eine sehr wichtige Funktion auf modernen CPUs, die kauen durch Daten viel schneller als der RAM liefern kann und unterstützt Rekursion. Design-Sprache ist stark geprägt durch einen stack, sichtbar, Unterstützung für lokale Variablen und Gültigkeitsbereich beschränkt sich auf die Methode Körper. Ein erhebliches problem mit dem stack ist die einzige, der dieser Ort benannt ist.
InformationsquelleAutor der Antwort Hans Passant
Gibt es ein sehr Interessantes/ausführliche Wikipedia-Artikel auf dieser Vorteile der stack-Maschine Befehl setzt. Ich brauchen würde, nennen es vollständig, so ist es einfacher, einfach einen link setzen. Ich werde einfach zitieren, der sub-Titel
InformationsquelleAutor der Antwort
Hinzufügen, ein wenig mehr auf den Stapel Frage. Das stack-Konzept leitet sich aus CPU-design, wo der Maschinencode, der in der arithmetisch-logischen Einheit (ALU) arbeitet auf Operanden, die sich auf dem stack. Ein Beispiel für einen mehrfachen Betrieb nehmen können, die beiden obersten Operanden vom stack, mehrere Sie Sie und legen das Ergebnis wieder auf den Stapel. Maschinensprache in der Regel hat zwei grundlegende Funktionen zum hinzufügen und entfernen von Operanden vom stack; PUSH und POP. In vielen cpu ' s dsp (digital signal processor) - und Maschine-Controllern (wie z.B. die Steuerung einer Waschmaschine) der stack befindet sich auf dem chip selbst. Dies gibt einen schnelleren Zugriff auf die ALU und konsolidiert die erforderlichen Funktionen in einem einzigen chip.
InformationsquelleAutor der Antwort skyman
Wenn das Konzept der stack - /heap wird nicht befolgt, und die Daten werden geladen und die random-Speicher ODER gespeicherten Daten gegen zufällige Speicher-Orte ... es wird sehr unstrukturiert und nicht verwaltete.
Diese Konzepte dienen zum speichern von Daten in eine vordefinierte Struktur, die um die Leistung zu verbessern Speichernutzung, ... und damit als data-Strukturen.
InformationsquelleAutor der Antwort Azodious
Kann man ein system zum arbeiten ohne Stapel, indem continuation-passing-style der Codierung. Dann rufen Sie frames werden Fortsetzungen zugeordnet werden, die garbage Collection-heap (der garbage collector würde müssen etwas stack).
Siehe Andrew Appel, alte Schriften: Kompilieren mit Fortsetzungen und Garbage Collection schneller sein können als Stack-Allokation
(Er könnte ein bisschen schief heute, weil der cache-Probleme)
InformationsquelleAutor der Antwort Basile Starynkevitch