« Fonctionnement d'un ordinateur/Les architectures à capacités » : différence entre les versions

Contenu supprimé Contenu ajouté
mAucun résumé des modifications
Ligne 1 :
Certains processeurs incorporent des méthodes qui permettent d’améliorer la sureté de fonctionnement ou la sécurité. Elles permettent d'éviter certaines attaques logicielles, comme des virus ou des accès non autorisés directement en matériel. Ces jeux d'instructions sont conçus en synergie avec certains systèmes d'exploitation. Il s'agit des capability based processors, ou '''architectures à capacités'''. Dans les grandes lignes, il s'agit d'architectures orientées objet, dont le langage machine est un langage orienté objet (bien qu'étant un langage machine).
 
==Les capacités : les principes de haut-niveau==
 
Sur les Capabilityarchitectures Basedà processorscapacité, la notion même d'adresses mémoire n'existe pas (ou presque). À la place, chaque donnée manipulée par le processeur est stockée dans un '''objet''', une sorte de conteneur générique placé quelque part dans la mémoire, sans que l'on ait de moyen de savoir où. Cet objet peut être absolument n'importe quoi : cela peut être un objet spécifié par le programmeur, ou des objets prédéfinis lors de la fabrication du processeur. Par exemple, on peut considérer chaque périphérique comme un objet, auquel on a défini des méthodes bien particulières qui permettront de communiquer avec celui-ci ou de le commander. Sur d'autres architectures, chaque programme en cours d’exécution est considéré comme un objet, avec des méthodes permettant d'agir sur son état. On peut ainsi stopper l’exécution d'un programme via des méthodes adaptées, par exemple. Mais ce qui va nous permettre d'adapter des langages de programmation orientés objet sur de telles architectures, c'est la possibilité de créer soi-même des objets non définis lors de la fabrication du processeur.
 
Au lieu d’utiliser des adresses mémoire et autres mécanismes divers et variés, chaque objet se voit attribuer un '''identifiant''' bien précis. Cet identifiant est unique à un objet (deux objets ne peuvent avoir le même identifiant), et ilqui ne change pas au cours du temps. : ilL'identifiant est définidéfinit lorsqu'unlors objetde estla créécréation de l'objet et ne peut être réutilisé pour un autre objet que lorsque l'objet possédant cet identifiant est détruit. Dans les grandes lignes, on peut voir cet identifiant comme une sorte d'adresse virtuelle, qui permet de localiser l'objet mais peut correspondre à une adresse physique totalement différente. De plus, chaque objet est associée à des '''autorisations d'accès'''. Par exemple, le code d'un système d'exploitation aura accès en écriture à certains objets critiques, qui contiennent des paramètres de sécurité critique, mais les autres programmes n'y auront accès qu'en lecture (voire pas du tout). Les droits d'accès ne seront pas les mêmes et les capacités différentes (parfois pour un même objet). Ces droits d'accès sont rassemblés dans une suite de bits, que l'on appelle une '''capacité'''. Celles-ci décrivent les droits d'accès, l'identifiant et éventuellement le type de la donnée. Souvent,Le latype partiepeut decorrespondre l'objetà ou de la capability spécifiant le type permet d'identifier certainsdes types prédéfinis, mais peut aussi être configurée de façoncorrespondre à utiliser des types définis par le programmeur : sa signification dépendra alors de ce qu'a décidé le programmeur.
 
Les instructions de lecture et écriture prennent comme argument un identifiant et une capacité. Pour avoir accès à un identifiant, le programme doit fournir automatiquement la capacité qui va avec : il doitet la charger dans des registres spécialisés. CesLes capacités sont mémorisées dans la mémoire RAM :et sont regroupés au même endroit. Dans le détail, chaque programme ou fonction a accès à une '''liste de capacités''' en mémoire RAM. Les instructions qui manipulent les registres de capacités ne peuvent pas, par construction, augmenter les droits d'accès d'une capacité : ils peuvent retirer des droits, pas en ajouter. Ce mécanisme interdit donc à tout sous-programme ou programme de modifier un objet qui n'est pas dans sa liste de capacité : le programme ne pourra pas récupérer la capacité et n'aura donc pas accès à l'objet voulue. Avec ce genre de mécanismes, il devient difficile d’exécuter certains types d'attaques, ce qui est un gage de sureté de fonctionnement indéniable. Du moins, c'est la théorie, :car tout repose sur l'intégrité des listes de capacité. : siSi on peut modifier celles-ci, alors il devient facile de pouvoir accéder à des objets auxquels on n’aurait pas eu droit.
 
==ImplémentationL'implémentation matérielle des capacités==
 
Divers mécanismes dépendants du processeur permettent d'implémenter l'héritage ou d'autres fonctionnalités objet en autorisant des manipulations, accès, copies ou partages temporaires de listes de capacités. Généralement, ce genre de fonctionnalité objet est géré directement au niveau des instructions du processeur : le processeur contient pour ce faire des instructions spéciales. Ces instructions sont souvent des instructions d'appels de fonction particulières. Pour ceux qui ne le savent pas, une instruction d'appel de fonction sert à demander au processeur d’exécuter une fonction bien précise. Sur les processeurs optimisés pour les langages procéduraux, une fonction est identifiée par son adresse, tandis que ces processeurs fournissent sa capacité à l'instruction chargée d’exécuter notre fonction. Sur ces processeurs, de nombreuses instructions d'appel de fonction sont disponibles : par exemple, l'instruction pour appeler une fonction définie dans la classe de l'objet qu'elle va manipuler ne sera pas la même de celle devant appeler une fonction héritée d'une autre classe : il faudra en effet faire quelques accès pour modifier ou accéder à des listes de capacités extérieures, etc.
Ligne 38 :
Objekt implémentait un Garbage Collector matériel assez simple, mais suffisamment efficace. Pour rappel, un garbage collector, ou ramasse-miettes, est un programme ou un système matériel qui se charge de supprimer de la mémoire les objets ou données dont on n'a plus besoin. Dans certains langages de programmation comme le C ou le C++ , on est obligé de libérer la mémoire à la main. Ce n'est pas le cas pour certains langages orientés objet, comme JAVA ou Lingo : un garbage collector permet de gérer la mémoire automatiquement, sans demander au programmeur de se fatiguer à le faire lui-même (du moins, en théorie). Ce garbage collector avait souvent besoin de déplacer des objets pour faire un peu de place en mémoire, et compacter les objets ensemble, pour faire de la place. Le fait que les objets soient manipulés avec une capacité facilitait énormément le travail du garbage collector matériel.
 
==Second exemple : l'Intel iAPX 432==
 
Passons maintenant à un autre processeur orienté objet un peu plus connu : l'Intel iAPX 432. Oui, vous avez bien lu : Intel a bel et bien réalisé un processeur orienté objet dans sa jeunesse. La conception du processeur Intel iAPX 432 commença en 1975, afin de créer un successeur digne de ce nom aux processeurs 8008 et 8080. Ce processeur s'est très faiblement vendu. Il faut dire que ce processeur avait des performances assez désastreuses et des défauts techniques certains. Par exemple, ce processeur ne contenait pas de mémoire cache et n'avait pas de registres (c'était une machin à pile). Autre détail : ce processeur ne pouvait pas effectuer directement de calculs avec des constantes entières autres que 0 et 1 (une sombre histoire de mode d'adressage immédiat non supporté). De plus, celui-ci avait été conçu pour exécuter en grande partie le langage ADA, un langage de programmation orienté objet très sécurisé et très utilisé dans le domaine de l'embarqué pour ses qualités intrinsèques. Malheureusement, le compilateur qui traduisait les codes sources écrits en ADA en programmes compréhensibles par le processeur était mauvais et avait une certaine tendance à massacrer les performances. Sans compter que l'ADA n'était pas très populaire chez les programmeurs et n'était utilisé que par les militaires et les entreprises travaillant sur des systèmes embarqués ou critiques, ce qui n'a pas aidé à faire vendre ce processeur.
 
===ModèleLe modèle mémoire de l'Intel iAPX 432===
 
Ce processeur utilisait la segmentation pour définir ses objets. Chaque objet était stocké dans un segment : toutes ses données et autres informations permettant de déterminer intégralement l'état d'un objet étaient regroupées dans un de ces segments. Chacun de ces segments est découpé en deux parties de tailles égales : une partie contenant les données d'un objet, et des informations supplémentaires destinées à gérer l'objet correctement. Ces informations pouvaient être des capacités pointant vers d'autres objets (pour créer des objets assez complexes), par exemple. Au fait : sur ce processeur, les capacité étaient appelées des Access Descriptors. Sur l'Intel iAPX432, chaque segment (et donc chaque objet) pouvait mesurer jusqu'à 64 kibioctets : c'est très peu, mais suffisant pour stocker des objets suffisamment gros pour que cela ne pose pas vraiment de problèmes. Ce processeur pouvait gérer jusqu'à 2^24 segments différents.
Ligne 48 :
L'Intel 432 possédait dans ses circuits un garbage collector matériel. Pour faciliter son fonctionnement, certains bits de l'object descriptor des objets permettaient de savoir si l'objet en question pouvait être supprimé ou non.
 
===SupportLe support de l'orienté objet sur l'Intel iAPX 432===
 
L'Intel 432 est conçu pour permettre l'utilisation de « types », de classes de base, déjà implémentées dans le processeur, mais cela ne suffit évidemment pas à supporter la programmation orientée objet. Pour cela, le processeur permet de définir ses propres classes, utilisables au besoin, et définies par le programmeur.
Ligne 58 :
Il est aussi possible pour le programmeur de définir de nouveaux types non supportés par le processeur, en faisant appel au système d'exploitation de l'ordinateur. Au niveau du processeur, chaque objet est typé au niveau de son object descriptor : celui-ci contient des informations qui permettent de déterminer le type de l'objet. Chaque type se voit attribuer un domain object qui contient toutes les fonctions capables de manipuler les objets de ce type et que l'on appelle le type manager. Lorsque l'on veut manipuler un objet d'un certain type, il suffit d'accéder à une capacité spéciale (le TCO) qui pointera dans ce type manager et qui précisera quel est l'objet à manipuler (en sélectionnant la bonne entrée dans la liste de capacité). Le type d'un objet prédéfini par le processeur est ainsi spécifié par une suite de 8 bits, tandis que le type d'un objet défini par le programmeur est défini par la capacité spéciale pointant vers son type manager.
 
===JeuLe jeu d'instruction de l'Intel iAPX 432=====
 
Ce processeur est capable d’exécuter pas moins de 230 instructions différentes. Le processeur supporte certains objets de base, prédéfinis dans le processeur. Il fournit des instructions spécialement dédiées à la manipulation de ces objets, et contient notamment des instructions d'appel de fonction assez élaborées. Il contient aussi des instructions n'ayant rien à voir avec nos objets, qui permettent de manipuler des nombres entiers, des caractères, des chaînes de caractères, des tableaux, etc. Beaucoup de ces instructions sont micro-codées. Le processeur est une machine à pile.
Ligne 65 :
 
On peut aussi préciser que ces instructions sont de longueur variable. Sur un processeur normal, les instructions ont une longueur qui est souvent multiple d'un octet, mais notre Intel iAPX 432 fait exception à cette règle : ses instructions peuvent prendre n'importe quelle taille comprise entre 10 et 300 bits, sans vraiment de restriction de taille. Sur l'Intel iAPX 432, les bits d'une instruction sont regroupés en 4 grands blocs, 4 champs, qui ont chacun une signification particulière. Comme vous allez le voir dans un instant, l'encodage des instructions reflète directement l'organisation de la mémoire en segments : le jeu d'instructions a dû s'adapter à l'organisation de la mémoire.
 
* Le premier champ s'appelle classe. Il permet de dire combien de données différentes l'instruction va devoir manipuler, et quelles seront leurs tailles.
* Le second champ, le champ format, n'utilise que 4 bits et a pour but de préciser si les données à manipuler sont en mémoire ou sur la pile.