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.
object-oriented
assembly
Nikolai Golub
la source
la source
Réponses:
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
struct
pour 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:
se résume à ceci:
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
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
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
la source