Comment fonctionne un microprocesseur

To the non-french speaker, note that you can translate the articles using the Google Trad widget situated at the bottom of all pages.


Dans cet article nous allons nous intéresser au fonctionnement d’un microprocesseur. Le microprocesseur est le cœur de l’ordinateur. C’est lui qui exécute l’ensemble des calculs.

Le premier processeur à avoir été commercialisé est l’Intel 4004, c’était un processeur à

16 branches cadencé à 740kHz et qui pouvait exécuter 90000 opérations par secondes.

A l’époque c’était une véritable révolution puisque ce microprocesseur était capable d’effectuer autant de calculs qu’un calculateur qui occupait une pièce entière.

intel4004

Nous, nous allons étudier le fonctionnement du 8086. Alors pourquoi le 8086 ? Tout simplement parce que j’ai appris l’assembleur sur ce processeur (qui fait parti de la famille des x86). Par ailleurs le 8086 est l’ancêtre de tous les processeurs Intel et cela va nous permettre de faire tourner des programmes codés pour le 8086 sur une machine actuelle. En effet Intel est parti du principe que tous les processeurs qu’il produit seraient rétro compatibles.

Voici à quoi ressemble le 8086 :

8086

Et voici son schéma fonctionnel :

schema8086

Afin de bien comprendre ce que nous allons faire par la suite il va être nécessaire de connaître le fonctionnement de ce microprocesseur. De manière générale, un microprocesseur est composé de trois éléments qui communiquent entre eux.

1) Les registres

Le premier élément est le registre. Un registre est en fait un emplacement mémoire placé dans le processeur. Cet espace mémoire ne dépasse généralement pas 10 octets et c’est une mémoire extrêmement rapide d’accès. Lorsque l’on programmera, nous utiliserons des registres afin d’effectuer des opérations ou stocker des informations nécessaires à l’exécution d’une instruction.

Il existe différent type de registre :

Les registres généraux : les quatre registres les plus utilisés sont AX, BX, CX, DX :

AX Utilisé pour les calculs arithmétiques, les traitement de chaînes de caractères ou transferts de données
BX Registre auxiliaire utilisé lui aussi pour les calculs arithmétiques
CX (Compteur) Utilisé comme compteur lors d’utilisation de boucles (loop)
DX (Données) Utilisé pour stocker des données mais aussi pour les opérations de multiplication et de divisions

Chacun de ces registres a une taille de 16 bits. Ils sont composés de deux parties de 8 bits chacune : la partie basse et la partie haute. Pour le registre AX nous avons donc:

AX =  AH + AL

AH = AHigh = partie haute
AL = ALow = partie basse

De même il est possible d’étendre la taille d’un registre en rajoutant un « E » (pour extended) devant le registre. Pour avoir un registre AX de 32 bits nous invoquerons donc le registre de cette manière : EAX.

registre.png
Crédits image : nayuki.io

Les registres offset ou pointeurs :

IP (pointeur d’instruction) indique la prochaine instruction à exécuter
SI (Index de source) Utilisé lors d’opérations sur les chaînes de caractères
DI (Index de destination) Utilisé lors d’opérations sur les chaînes de caractère
SP (Pointeur de pile) Indique le sommet de la pile
BP (Pointeur de base) Utilisé pour accéder aux données de la pile lors d’appel de sous-programmes

De même que pour les registres généraux, on peut étendre leur taille en ajoutant le « E » de « extended ». Par contre ils ne sont pas divisés en deux parties (partie basse et haute). De plus le registre IP n’est pas directement modifiable pour des raisons que nous verrons plus tard.

Le registre flag (registres d’état) est utilisé afin de contenir l’état d’une opération. Sa version étendue « EFLAG » est  constituée de 32 bits (soit 32 flags différents). Le 8086 ne travaille qu’avec 16 bits :

registreEFLAG

CF (Carry Flag) Indicateur de retenu, si le résultat d’une opération est plus grand que le nombre de bits disponibles alors le bit supplémentaire sera placé dans le CF.
PF (Parity Flag) Indicateur de parité (pair = 1 / impaire = 0)
AF (Auxiliaire Carry Flag) Identiques à CF
ZF (Zero Flag) Si le résultat d’une opération = 0 alors ZF =1
SF (Sign Flag) SF = 1 si le résultat est signé (positif ou négatif)
IF (Interrupt Flag) Indicateur d’interruption, si IF = 1 alors les interruptions sont prises en compte sinon non.
DF (Direction Flag) Indicateur de direction, contrôle la direction de déplacement des pointeurs lors d’instruction de chaîne.
OF (Overflow Flag) Indicateur de déplacement, permet de déceler les erreurs mathématiques de type overflow.
TF (Trap Flag) est utilisé afin que le microprocesseur exécute du code pas à pas.

Les registres de segment

Le 8086 possède 4 registres de segment : CD, DS, SS, ES. Ces registres sont chargées de sélectionner les différents segments de mémoire en pointant sur le début de chacun d’entre eux.

CS (Code Sgement) Pointe le segment qui contient les codes des instructions en cours
DS (Data Segment) Pointe sur le segment des variables globales du programme
ES (Extra Segment) Segment supplémentaire parfois utilisé pour stocker des chaînes de caractères
SS (Stack Segment) Pointe sur la pile (on verra plus tard ce que c’est)

Voila pour les registres, il est important de les connaître puisque nous nous en servirons très souvent.

2) L’unité arithmétique et logique

C’est en quelques sorte la pièce maîtresse d’un processeur. Elle peut effectuer deux opérations : arithmétique (addition, soustraction, division et multiplication) et logique ( AND, OR, XOR, NOR…). Ces opérations sont décrites ici.

La FPU fait la même chose sauf qu’elle s’occupe des nombres flottants (à virgule).

Souvent nous avons un accumulateur dans l’UAL qui permet de stocker le résultat de l’opération précédente.

Schématiquement on représente l’UAL de cette manière :

ual

Nous avons ici 3 entrées et 2 sorties. Les entrées A et B sont les entrées sur lesquelles on présente les données à traiter. L’entrée F représente l’opération à effectuer. La sortie R est le résultat de l’opération tandis que la sortie D est utilisée pour mettre à jour les flags (registre d’états).

L’UAL est composé de plusieurs « portes » qui sont chacune chargées d’effectuer une opération. Voici comment est exécutée l’opération « AND » entre deux opérandes A et B dans l’UAL :

portesUAL

A l’intérieur de ces portes tout est géré électriquement et via des tables de vérité. Ces portes sont des éléments minuscules qui ne s’ouvriront qu’à certaines conditions. Si elle s’ouvre alors le courant passe (donc le bit est chargé donc vaut 1) si elle ne s’ouvre pas alors le courant ne passe pas (donc le bit n’est pas chargé donc vaut 0).

Dans le cas de la porte « AND » il faut que le premier bit de l’opérande A et le premier bit de l’opérande B soient à 1 pour que la porte s’ouvre et donc que le résultat r0 soit égal à 1.

Il existe des opérations beaucoup plus complexes qui nécessitent l’imbrication de plusieurs portes différentes. Les calculs sont donc plus complexes mais suivent toujours le même schéma.

3) Les circuits de contrôle

Vous avez pu le voir, l’ensemble du microprocesseur est parcouru par des bus. Les données sont transmises d’un endroit à un autre dans un ordinateur grâce aux bus qui sont composés de câbles très fins. A savoir qu’un câble permet de transmettre un bit à la fois. Donc un bus de 26 câbles permet de transmettre 26 bits en même temps !

Il existe trois types de bus différents :

Le bus de données :

Il sert à transporter des données de la mémoire vers le processeur et vis vers ça. C’est un bus dit « bidirectionnel ».

Le bus d’adresse :

Celui-ci relie le processeur à la mémoire vive et est unidirectionnel. Lorsque le processeur a besoin d’une information stockée sur la mémoire vive il va tout simplement envoyer l’adresse de cette donnée à la mémoire. La mémoire vive va par la suite lui envoyer l’information en question via le bus de données.

Le bus de contrôle :

Permet de contrôler les opérations réalisées sur le bus.

L’ensemble est contrôlé par une horloge qui est cadencé en Hertz. Un processeur de 3.4 giga Hertz effectue 3.4 milliards d’instructions par seconde.


Maintenant, vous savez ce qu’il y a comme composants dans un microprocesseur. Cependant vous ne connaissez pas encore l’enchaînement logique qui permet à un micro processeur de fonctionner. En voici une description :

La première chose à faire va être de charger une instruction contenue en mémoire. Cette instruction (dans le 8086) est préchargée dans la file d’attente de 6 bits. Cela permet de réduire le temps d’attente entre l’exécution de deux instructions. En même temps que l’instruction va être charger, le compteur de programme va être incrémenté afin de spécifier l’adresse mémoire de l’instruction à exécuter après. Par la suite l’instruction va être décodée dans le décodeur ( voir séquencer par le séquenceur si elle est trop compliquée à traiter d’un coup) et si besoin est, le processeur va aller chercher les données en mémoire via les bus dont il dispose. Par exemple si nous voulons faire une addition : 1 + 2, nous aurons besoin du chiffre 1 et du chiffre 2. Ces deux chiffres sont contenus dans la mémoire vive et donc il va falloir aller les chercher via les bus. Quant à l’addition, elle est contenue dans la mémoire centrale.

Le processeur avant de demander à la mémoire vive les informations dont il a besoin va interroger la mémoire cache. La mémoire cache c’est une quantité de mémoire variable dans laquelle sont stockées les données les plus souvent utilisées. Cette mémoire est très rapide d’accès et permet donc de ne pas avoir à refaire de demande à la mémoire vive (ce qui prend beaucoup de temps à l’échelle d’un microprocesseur).

Donc le processeur va envoyer une adresse à la mémoire (via le bus d’adresse) vive en lui demandant de lui renvoyer l’information contenue à cette adresse (via le bus de données).

Ensuite le travail de calcul va être délégué à l’UAL (ou la FPU suivant l’action). Via le système de porte et de tables de vérité décrit plus haut, l’UAL sera en mesure d’effectuer le calcul. Une fois le calcul fini, le processeur va ranger le résultat dans la mémoire vive (en spécifiant une adresse) et si c’est nécessaire va mettre à jour le registre FLAG. Puis il va passer à l’instruction suivante.

Voilà, je pense avoir fait le tour. Il est fort possible que j’ai oublié quelques éléments. De toute manière au fur à et à mesure de mon avancé sur l’assembleur et le cracking je mettrais à jour cet article.

3 commentaires

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s