Avant d'étudier le jeu d'instructions, il nous paraît intéressant de détailler quelques caractéristiques de cette architecture afin de mieux comprendre le sens de certaines instructions de gestion de la mémoire ou autre.
Dans la mesure où l'ensemble des processeurs Intel assurent tous une totale compatibilité binaire, nous avons décidé d'étudier cette architecture à travers celle du processeur Pentium qui représente l'état de l'art de cette architecture (la documentation du P6 n'étant pas encore disponible).
Le processeur Pentium a deux modes d'exécution primaires et un mode de gestion du système (dédié au contrôle de la consommation ainsi qu'à certaines caractéristiques des OEM). Ces modes sont :
L'organisation de la mémoire concerne la segmentation et la pagination. L'un ou l'autre de ces mécanismes, voire les deux, peuvent être utilisés simultanément par les processeurs Intel.
Une adresse issue du programme est appelée une << adresse logique >>. Les mécanismes matériels liés à la segmentation traduisent cette adresse logique en une adresse vers un espace d'adressage non segmenté, continu, appelé << adresse linéaire >>. Puis les mécanismes de pagination convertissent cette adresse linéaire en une adresse physique.
Afin de bien comprendre ce qui va suivre, il est intéressant de revenir sur le concept de segmentation. L'adresse logique est vue comme un déplacement à l'intérieur du segment. À chaque segment est associé un descripteur qui contient son adresse de base, sa taille limite ainsi que des informations de protection. Si le déplacement ne dépasse pas la taille limite, et si aucune autre condition n'existe qui pourrait empêcher la lecture du segment, alors le déplacement et l'adresse de base sont ajoutés pour former une adresse linéaire.
Deux types de modèles de mémoire peuvent être utilisés :
L'intérêt d'un modèle de mémoire segmenté est que les déplacements dans l'espace d'adressage sont testés individuellement et que l'accès à chaque segment peut être individuellement controlé. Un pointeur vers un espace d'adressage segmenté est donc constitué de deux parties :
L'adresse linéaire fournie par le mécanisme de segmentation peut être directement utilisée pour pointer vers un vaste espace d'adressage physique, ou alors la pagination peut être utilisée pour simuler cet espace à partir d'une petite quantité de RAM et d'espaces disques. Quand la pagination est utilisée, l'adresse linéaire est convertie en une adresse physique ou une exception est générée. L'exception permet au système d'exploitation de charger la page concernée à partir du disque.
La pagination est différente de la segmentation dans la mesure où elle utilise des tailles fixes de pages (sur l'architecture Intel), contrairement au mécanisme de segmentation qui adapte la taille du segment à la structure de données qu'il contient. Ainsi, si seule la segmentation est utilisée, la structure de données qui est présente en mémoire physique sera entièrement en mémoire. Si la pagination est utilisée, une structure de données peut être partiellement en mémoire et partiellement sur le disque.
La figure décrit le mécanisme de pagination du Pentium. Deux niveaux de tables sont utilisés pour adresser une page en mémoire physique. Chaque table est un tableau d'entrées de 32 bits qui est contenu, lui-même, dans une page de 4 Ko. Les dix bits de poids fort de l'adresse linéaire (c'est-à-dire l'adresse obtenue après segmentation) servent à indexer le répertoire de tables. L'entrée indexée contient l'adresse de la table de pages utile à la traduction d'adresse. Cette dernière est indexée par la partie table de l'adresse linéaire (10 bits). L'entrée désignée pointe sur l'adresse de base de la page à laquelle il faut ajouter le déplacement (les 12 bits de poids faible) de l'adresse pour obtenir l'adresse physique. Notons que ce mécanisme ne permet d'adresser que des pages de taille fixe (4 Ko). Il est possible d'adresser des pages de plus grande taille (jusqu'à 4 Mo), mais, pour des raisons commerciales, le mécanisme utilisé pour l'adressage de telles pages n'est pas diffusé par Intel. On peut toutefois remarquer qu'un répertoire de tables peut adresser un espace linéaire de 4 Go (1024 pages de 4 Ko). Il suffit donc de modifier la granularité de cet espace pour adresser des pages de taille supérieure à 4 Ko.
Le processeur Pentium contient 16 registres pouvant être utilisés par le programmeur. La figure récapitule l'ensemble de ces registres.
Les registres généraux sont utilisés par l'ensemble des opérations entières (logiques, arithmétiques, calcul d'adresses). Leurs noms sont dérivés des registres du processeur 8086 qui peuvent toujours être utilisés pour désigner les 16 bits de poids faible. Il est à noter que certains de ces registres sont utilisés de manière spécifique par quelques instructions. Par exemple, les instructions de manipulation de chaînes de caractères utilisent les registres ECX, ESI et EDI pour leurs opérandes. En assignant des registres spécifiques à certaines fonctions, les instructions peuvent être codées de manière plus compacte et l'étape de décodage est d'autant plus courte. Ces instructions incluent les multiplication/division double-précision, les entrées/sorties, la manipulation des chaînes, les traductions, les boucles, les opérations de piles, etc...
Les registres de segments contiennent les sélecteurs de segments (sur 16 bits) associés aux différentes formes d'accès mémoire. À n'importe quel instant, six segments de la mémoire sont immédiatement disponibles. Les registres de segments conservent donc le sélecteur associé à chacun de ces segments. Chaque registre est associé à un type de segment particulier (CS pour le segment de code, DS pour le segment de données, SS pour le segment de pile). Les registres DS, ES, FS et GS permettent de disposer de quatre segments de données simultanément. Ces quatre segments de données contribuent à l'efficacité et à la sécurité des accès à différents types de structure de données.
Les registres de contrôle et de statut permettent la modification de l'état du processeur.
Par ailleurs, pour compléter cette description de l'architecture, l'unité flottante contient également un certain nombre de registres :
Tous les registres flottants sont adressables. Cependant, comme la plupart des instructions flottantes utilisent de façon implicite le registre du haut de la pile, ce dernier constitue un goulot d'étranglement. Intel essaie de modérer ce défaut de l'architecture en autorisant le couplage de l'instruction FXCH (Floating-point register exchange, cette instruction échange le contenu d'un registre avec celui placé en haut de pile) avec toute autre instruction flottante.
Les nombres réels différent par la taille de leur mantisse qui est de 23 bits pour le format simple précision, 52 bits en double précision et 63 bits pour celui des réels étendus. Les formats simple et double précision correspondent aux formats standards IEEE-754 utilisés dans la plupart des microprocesseurs.
Le stockage des nombres flottants dans la pile de registres se fait
uniquement dans le format des réels étendus (80 bits) ; une conversion est
effectuée avant chaque lecture et écriture.
Après avoir détaillé quelques caractéristiques de cette architecture, nous
allons pouvoir aborder l'étude de son jeu d'instructions.