Comment les «objets» et «classes» OOP sont-ils organisés en mémoire en termes de langage d'assemblage?

13

Comment les objets sont-ils organisés en mémoire?

Par exemple, je sais qu'une fonction est un morceau de code en mémoire, qui attend des paramètres via la pile et / ou les registres et gère son propre cadre de pile.

Mais les objets sont une structure beaucoup plus compliquée. Comment sont-ils organisés? Chaque objet a-t-il des «liens» vers des méthodes et passe-t-il une adresse à cette méthode?

Ce serait formidable de voir une bonne explication de ce sujet.

UPD. J'ai rendu la question plus exacte et je m'intéresse principalement aux langages de saisie statique.

Nikolai Golub
la source
4
Il peut varier énormément entre les différentes langues, en particulier entre les langues typées dynamiquement et statiquement. Pouvez-vous limiter votre question aux langues OO qui vous intéressent le plus?
Bart van Ingen Schenau
J'ai mis à jour la question, donc je pense que les langues typées dynamiquement sont plus difficiles à comprendre.
Nikolai Golub

Réponses:

17

S'il n'y a pas de répartition dynamique (polymorphisme), les "méthodes" ne sont que des fonctions sucrées, peut-être avec un paramètre supplémentaire implicite. Par conséquent, les instances de classes sans comportement polymorphe sont essentiellement des C structpour la génération de code.

Pour la répartition dynamique classique dans un système de type statique, il existe essentiellement une stratégie prédominante: les vtables. Chaque instance obtient un pointeur supplémentaire qui fait référence à (une représentation limitée de) son type, le plus important étant la table virtuelle: un tableau de pointeurs de fonction, un par méthode. Étant donné que l'ensemble complet des méthodes pour chaque type (dans la chaîne d'héritage) est connu au moment de la compilation, on peut attribuer des indices consécutifs (0..N pour N méthodes) aux méthodes et appeler les méthodes en recherchant le pointeur de fonction dans la table virtuelle en utilisant cet index (en passant à nouveau la référence d'instance comme paramètre supplémentaire).

Pour les langages basés sur des classes plus dynamiques, les classes elles-mêmes sont généralement des objets de première classe et chaque objet a une référence à son objet de classe. L'objet classe, à son tour, possède les méthodes d'une manière dépendante du langage (dans Ruby, les méthodes sont une partie centrale du modèle objet, en Python, ce ne sont que des objets fonction avec de minuscules enveloppes autour d'eux). Les classes stockent généralement également les références à leurs superclasses et délèguent la recherche des méthodes héritées à ces classes pour faciliter la métaprogrammation qui ajoute et modifie les méthodes.

Il existe de nombreux autres systèmes qui ne sont pas basés sur des classes, mais ils diffèrent considérablement, donc je ne choisirai qu'une alternative de conception intéressante: lorsque vous pouvez ajouter de nouveaux (ensembles de) méthodes à tous les types à volonté n'importe où dans le programme ( ex: classes de types dans Haskell et traits dans Rust), l'ensemble complet des méthodes n'est pas connu lors de la compilation. Pour résoudre ce problème, on crée une table virtuelle par trait et les transmet lorsque l'implémentation du trait est requise. Autrement dit, un code comme celui-ci:

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

se résume à ceci:

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);

Cela signifie également que les informations vtable ne sont pas intégrées dans l'objet. Si vous voulez des références à une "instance d'un trait" qui se comportera correctement lorsque, par exemple, stockées dans des structures de données qui contiennent de nombreux types différents, vous pouvez créer un gros pointeur (instance_pointer, trait_vtable) . Il s'agit en fait d'une généralisation de la stratégie ci-dessus.


la source
5

C'est une réponse au sens du proverbe "si vous donnez à un homme un poisson, vous le nourrissez pendant une journée, tandis que si vous lui apprenez à pêcher, vous le nourrissez à vie" car votre question est très large

1. rechercher des sources d'information ouvertes

Google pour la «programmation orientée objet d'assemblage» répertorie un grand nombre de ressources pertinentes différentes.

Par exemple, la programmation orientée objet dans l'assemblage, Ethan J. Eldridge, 15 décembre 2011 est venu comme troisième lien et semble bon

2. apprendre du code manuscrit existant

Vous pouvez voir comment cela fonctionne en étudiant les codes sources écrits avec certains langages d'assemblage populaires avec la POO explicitement déclarée, par exemple

3. apprendre des modèles de code générés par les compilateurs

Vous pouvez voir comment cela fonctionne en étudiant les fichiers de langage d'assemblage intermédiaires produits par les compilateurs OOP de votre choix. Les compilateurs C ++ et FreePascal peuvent être configurés pour que vous puissiez voir à quoi ressemble la transcription du code OOP de haut niveau dans le code du langage d'assemblage

4. résolvez le puzzle avec votre bon sens

Il est maintenant trop tard car vous connaissez déjà les indices des autres réponses. Mais avant qu'Internet soit si facile à rechercher et avant qu'il n'y ait des sites où vous pouvez obtenir votre réponse sans aucun effort en quelques heures gratuitement par un volontaire qui l'a appris à la dure, la seule méthode de travail disponible gratuitement pour quiconque était

Demandez-vous: "comment pourrais-je le mettre en œuvre?"

Très souvent, après plusieurs jours de réflexion en arrière-plan et après avoir jeté plusieurs ébauches de papier, vous constaterez que la solution que vous avez trouvée est très similaire à la solution que d'autres programmeurs ont proposée et déjà mise en œuvre


Maintenant, ma réponse est basée sur l'opinion, ne répond pas directement à la question d'OP et les utilisateurs expérimentés peuvent me dévaloriser librement

xmojmr
la source