Wie sind OOP-Objekte und -Klassen in Bezug auf die Assemblersprache im Speicher organisiert?


13

Wie sind Objekte im Gedächtnis organisiert?

Ich weiß zum Beispiel, dass eine Funktion ein Stück Code im Speicher ist, der Parameter über den Stack und / oder die Register erwartet und seinen eigenen Stack-Frame verarbeitet.

Objekte sind jedoch eine viel kompliziertere Struktur. Wie sind sie organisiert? Verfügt jedes Objekt über "Links" zu Methoden und übergibt die Adresse an sich selbst an diese Methode?

Es wäre toll, eine gute Erklärung für dieses Thema zu sehen.

UPD. Ich habe die Frage genauer gestellt und mich hauptsächlich für das statische Tippen von Sprachen interessiert.


4
Es kann stark zwischen verschiedenen Sprachen variieren, insbesondere zwischen dynamisch und statisch getippten Sprachen. Können Sie Ihre Frage auf die OO-Sprachen eingrenzen, die Sie am meisten interessieren?
Bart van Ingen Schenau

Ich habe die Frage aktualisiert, daher denke ich, dass dynamisch getippte Sprachen schwerer zu verstehen sind.
Nikolai Golub

Antworten:


17

Wenn es keinen dynamischen Versand (Polymorphismus) gibt, sind "Methoden" nur zuckerhaltige Funktionen, möglicherweise mit einem impliziten zusätzlichen Parameter. Dementsprechend sind Instanzen von Klassen ohne polymorphes Verhalten im Wesentlichen structCs zum Zweck der Codegenerierung.

Für den klassischen dynamischen Versand in einem statischen Typsystem gibt es grundsätzlich eine vorherrschende Strategie: vtables. Jede Instanz erhält einen zusätzlichen Zeiger, der auf ihren Typ verweist (eine begrenzte Darstellung davon), vor allem auf die vtable: Ein Array von Funktionszeigern, einen Zeiger pro Methode. Da der vollständige Satz von Methoden für jeden Typ (in der Vererbungskette) zur Kompilierungszeit bekannt ist, können den Methoden aufeinanderfolgende Indizes (0..N für N Methoden) zugewiesen und die Methoden aufgerufen werden, indem der Funktionszeiger in nachgeschlagen wird Die vtable verwendet diesen Index (wobei die Instanzreferenz erneut als zusätzlicher Parameter übergeben wird).

Bei dynamischeren klassenbasierten Sprachen sind Klassen in der Regel selbst erstklassige Objekte, und jedes Objekt verfügt stattdessen über einen Verweis auf sein Klassenobjekt. Das Klassenobjekt wiederum besitzt die Methoden in gewisser sprachabhängiger Weise (in Ruby sind Methoden ein Kernbestandteil des Objektmodells, in Python sind sie nur Funktionsobjekte mit winzigen Umhüllungen). Die Klassen speichern normalerweise auch Verweise auf ihre Oberklasse (n) und delegieren die Suche nach geerbten Methoden an diese Klassen, um die Metaprogrammierung zu unterstützen, die Methoden hinzufügt und ändert.

Es gibt viele andere Systeme, die nicht auf Klassen basieren, die sich jedoch erheblich unterscheiden. Ich werde daher nur eine interessante Designalternative herausgreifen: Wenn Sie an einer beliebigen Stelle im Programm neue (Gruppen von) Methoden zu allen Typen hinzufügen können ( B. Typklassen in Haskell und Eigenschaften in Rust), ist der vollständige Methodensatz beim Kompilieren nicht bekannt. Um dies zu beheben, erstellt man eine vtable pro Merkmal und leitet sie weiter, wenn die Implementierung des Merkmals erforderlich ist. Das heißt, Code wie folgt:

void needs_a_trait(SomeTrait &x) { x.method2(1); }
ConcreteType x = ...;
needs_a_trait(x);

ist wie folgt zusammengestellt:

functionpointer SomeTrait_ConcreteType_vtable[] = { &method1, &method2, ... };
void needs_a_trait(void *x, functionpointer vtable[]) { vtable[1](x, 1); }
ConcreteType x = ...;
needs_a_trait(x, SomeTrait_ConcreteType_vtable);

Dies bedeutet auch, dass die vtable-Informationen nicht in das Objekt eingebettet sind. Wenn Sie Verweise auf eine "Instanz eines Merkmals" wünschen, die sich korrekt verhält, wenn sie beispielsweise in Datenstrukturen gespeichert werden, die viele verschiedene Typen enthalten, können Sie einen Fettzeiger erstellen (instance_pointer, trait_vtable). Dies ist eigentlich eine Verallgemeinerung der obigen Strategie.


5

Dies ist eine Antwort im Sinne des Sprichworts "Wenn Sie einem Mann einen Fisch geben, füttern Sie ihn für einen Tag, während Sie ihm das Fischen beibringen, ernähren Sie ihn fürs Leben", da Ihre Frage sehr weit gefasst ist

1. Nach offenen Informationsquellen suchen

Google für "Assembly Object Oriented Programming" listet viele verschiedene relevante Ressourcen auf.

Beispiel: Objektorientierte Programmierung in der Baugruppe, Ethan J. Eldridge, 15. Dezember 2011, kam als drittes Glied und sieht gut aus

2. Lernen Sie aus vorhandenem handgeschriebenem Code

Sie können sehen, wie es funktioniert, indem Sie Quellcodes untersuchen, die mit einigen gängigen Assemblersprachen geschrieben wurden, für die OOP explizit deklariert wurde, z

3. Lernen Sie aus von Compilern generierten Codemustern

Sie können sehen, wie es funktioniert, indem Sie die Assemblersprachendateien untersuchen, die von OOP-Compilern Ihrer Wahl erstellt wurden. Sowohl C ++ - als auch FreePascal-Compiler können so konfiguriert werden, dass Sie sehen, wie die Transkription des OOP-Codes auf hoher Ebene in den Assembler-Code aussieht

4. Lösen Sie das Rätsel mit gesundem Menschenverstand

Jetzt ist es zu spät, da Sie die Hinweise bereits aus anderen Antworten kennen. Aber bevor das Internet so einfach zu durchsuchen war und es Websites gab, auf denen Sie Ihre Antwort ohne großen Aufwand innerhalb weniger Stunden kostenlos von einem Freiwilligen erhalten konnten, der es auf die harte Tour gelernt hatte, war die einzige kostenlose Arbeitsmethode, die es für jedermann gab

Fragen Sie sich: "Wie würde ich es implementieren?"

Sehr oft stellten Sie nach mehreren Tagen des Hintergrunddenkens und dem Wegwerfen mehrerer Papierentwürfe fest, dass die von Ihnen entwickelte Lösung der von anderen Programmierern entwickelten und bereits implementierten Lösung sehr ähnlich ist


Jetzt basiert meine Antwort auf der Meinung, beantwortet die Frage von OP nicht direkt, und erfahrene hochrangige Benutzer können mich frei ablehnen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.