Modèle d’architecture de Von Neumann

sources : https://pixees.fr/informatiquelycee/n_site/nsi_prem_von_neu.html
https://fr.wikipedia.org/wiki/Architecture_de_von_Neumann

L’architecture de von Neumann est un modèle structurel d’ordinateur dans lequel une unité de stockage (mémoire) unique sert à conserver à la fois les instructions et les données demandées ou produites par le calcul. Les ordinateurs actuels sont tous basés sur des versions améliorées de cette architecture.

L’architecture de von Neumann décompose l’ordinateur en 4 parties distinctes :

  • l’unité arithmétique et logique (UAL ou ALU en anglais) ou unité de traitement : son rôle est d’effectuer les opérations de base ;
  • l’unité de contrôle ou de commande (control unit), chargée du « séquençage » des opérations ;
  • la mémoire qui contient à la fois les données et le programme qui indiquera à l’unité de contrôle quels sont les calculs à faire sur ces données ;
  • les dispositifs d’entrée-sortie, qui permettent de communiquer avec le monde extérieur.

 

 

Principaux composants

Le microprocesseur

Intel CPU Core i7 6700K

Le microprocesseur (ou unité centrale de traitement, UCT, en anglais Central Processing Unit, CPU) est un composant essentiel qui exécute les instructions machine des programmes informatiques.

Remarque : il est le plus souvent amovible, placé sur un support appelé socket, et équipé d’un radiateur et d’un ventilateur (c’est le composant de la carte mère le plus gourmand en énergie).

Il est schématiquement constitué de 3 parties :

  • l’unité arithmétique et logique (ALU) est chargée de l’exécution de tous les calculs que peut réaliser le microprocesseur :
  • les registres permettent de mémoriser de l’information (donnée ou instruction) au sein même du CPU, en très petite quantité ;
  • l’unité de contrôle permet d’exécuter les instructions (les programmes)
    elle joue le rôle de « chef d’orchestre » : récupération des instructions et des données pour les envoyer à l’ALU.

 

La mémoire

source : https://fr.wikipedia.org/wiki/Mémoire_(informatique)

La mémoire permet de stocker des données et des programmes.

La mémoire se divise entre :

  • mémoire volatile contenant les programmes et données en cours de fonctionnement) : cette mémoire perd son contenu lorsqu’elle n’est plus alimentée.
  •  mémoire permanente contenant les programmes et données de base de la machine : cette mémoire le disparait pas à la mise hors tension.

Dans la plupart des mémoires, les informations sont classées par adresses : chaque octet est accessible par une adresse unique.

 

Pour des raisons économiques, les mémoires sont en général divisées en plusieurs familles :

Une mémoire de masse ou mémoire de stockage

HDD

SSD

sert à stocker à long terme des grandes quantités d’informations. Les technologies les plus courantes de mémoires de masse sont électromécaniques (disques durs – HDD) ou à semi-conducteurs (SSD, clefs USB, …), elles visent à obtenir une capacité de stockage élevée à faible coût et ont généralement une vitesse inférieure aux autres mémoires.

ordres de grandeur :

  • capacité : jusqu’à 10 To (HDD)
  • vitesse : jusqu’à 500 Mo/s (SSD)

 

La mémoire vive ou RAM

SDRAM

SDRAM

C’est l’espace principal de stockage du microprocesseur, mais il s’agit d’une mémoire volatile.

Appelée RAM (Random Access Memory) car le temps d’accès aux données est faible et ne dépend pas de l’emplacement.

ordres de grandeur :

  • capacité : jusqu’à 32 Go
  • vitesse : jusqu’à 2 Go/s

 

Une mémoire cache

La RAM est rapide, mais le microprocesseur l’est encore plus ! Afin de ne pas limiter ses performances en l’obligeant à attendre (on parle de goulot d’étranglement), on utilise de petites unités de mémoires, beaucoup plus rapides, mais nettement plus chères !

Différents niveaux de mémoire

Différents niveaux de mémoire

Ses mémoires cache servent à conserver un court instant des informations fréquemment consultées. Elles ont une très grande vitesse, et un coût élevé pour une faible capacité de stockage.

ordres de grandeur :

  • capacité : quelques ko (L1) à quelques Mo (L2)
  • vitesse : jusqu’à 5 Go/s

 

Le registre de processeur

Il est intégré au processeur. Ce type de mémoire est très rapide mais aussi très cher et est donc réservé à une très faible quantité de données.

ordres de grandeur :

  • capacité : quelques dizaines d’octets
  • vitesse : jusqu’à 30 Go/s

 

Les bus

Pour que les données circulent entre les différentes parties d’un ordinateur (mémoire, CPU et les entrées/sorties), il existe des systèmes de communication appelés bus. Il en existe de 3 grands types :

  • Le bus d’adresse permet de faire circuler des adresses
    par exemple l’adresse d’une donnée à aller chercher en mémoire ;
  • Le bus de données permet de faire circuler des données ;
  • Le bus de contrôle permet de spécifier le type d’action
    exemples : écriture d’une donnée en mémoire, lecture d’une donnée en mémoire.

 

 

 


Les circuits logiques

Dans les microprocesseurs, les opérations booléennes sont réalisées par des transistors formant ce que l’on appelle des circuits logiques.

Un circuit logique prend en entrée et donne en sortie des signaux électriques à deux états (HAUT et BAS). Il existe deux catégories de circuit logique :

  • les circuits combinatoires (les états en sortie dépendent uniquement des états en entrée)
  • les circuits séquentiels (les états en sortie dépendent des états en entrée ainsi que du temps et des états antérieurs)

On représente les circuits logiques à l’aide de schémas appelés logigrammes (voir l’article sur les booléens pour le détail des symboles).

Voici quelques actions élémentaires que l’on peut réaliser à l’aide de circuits logiques :

Additionneur

L’addition de deux bits peut être « simplement » réalisée grâce à une porte XOR :

\(a\) \(b\) \(a\;XOR\;b\)
0 0 0
0 1 1
1 0 1
1 1 0

Mais cette opération ne prend pas en compte la retenue, car elle donne le résultat sur un seul bit,  :

\(1_b+1_b=10_b\) : le \(1_b\) de \(10_b\) tient pas dans un mot de 1 bit !

Pour additionner des nombres codés sur plusieurs bits (comme les entiers naturels par exemple), il faut réaliser plusieurs additions de bits, mais en tenant compte de la retenue :

Schéma interactif

En cliquant sur les entrées logiques E1, E2 et Cin, réaliser l’addition 1+0 avec une retenue de 1 :

Cet additionneur permet d’additionner 2 bits (E1 et E2) en tenant compte de la retenue entrante (« Cin » , carry in en anglais). En sortie on obtient le résultat de l’addition (S) et la retenue sortante (« Cout », carry out).

Activité
Compléter la table de vérité de cet additionneur :
\(E1\) \(E2\) \(Cin\) \(Cout\) \(S\)
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

 

Pour réaliser une addition sur des nombres de plusieurs bits, on combine plusieurs circuits logiques d’addition :

Schéma interactif

Réaliser l’opération 4h + Ah :

Remarques :

  • Le premier bit de retenue entrante vaut 0
  • Le dernier bit de retenue sortante est « perdu » lorsqu’il y a dépassement de la capacité (longueur du mot)

 

Inverseur

Activité

Réaliser le circuit logique d’un inverseur en suivant les étapes suivantes :

A partir de l’expression logique de l’inversion (voir l’article sur la représentation des nombres entiers relatifs), réaliser le logigramme d’un inverseur

 

Mémoire

Il existe plusieurs circuit logiques, appelés bascules, permettant de mémoriser des bits.

Exemple, la bascule D à verrouillage :

L’entrée D correspond au bit à mémoriser. Pour effectuer la mémorisation, il faut activer le bit de validation V. La sortie Q prend alors la valeur de D à l’instant de la validation, lorsque V passe de 0 à 1 (on parle de front montant de V). Tant que V reste à 0, Q garde la valeur mémorisée, quelle que soit la valeur de D.

Les circuits intégrés de mémoire vive comportent de très nombreuses bascules, accessibles par une adresse donnant accès à 8 bits (soit un octet) à la fois, en lecture ou en écriture.

Exemple : mémorisation d’un octet avec la bascule D à verrouillage :

 


Instructions machine

Le CPU ne gère que des grandeurs booléennes : les instructions exécutées au niveau du CPU sont donc codées en binaire. L’ensemble des instructions exécutables directement par le microprocesseur constitue ce que l’on appelle le langage machine.

Les langages de programmation « évolués » (Python, C++, …), destinés à être utilisés par des humains, se composent d’instructions complexes, opérant sur des types de données beaucoup plus complexes que des booléens.

Il faudra donc passer par une étape de « conversion » du langage évolué vers le langage machine, chaque instruction du langage « évolué » donnant lieu à un grand nombre d’instructions « élémentaires » du langage machine. On distinguera l’opération de compilation (conversion de tout le code évolué en langage machine) de l’opération d’interprétation (la conversion est réalisée au fur et à mesure du déroulement du code).

Une instruction machine est une chaîne binaire composée principalement de 2 parties :

  • le champ « code opération » qui indique au processeur le type de traitement à réaliser.
    Par exemple le code « 0010 0110 » donne l’ordre au CPU d’effectuer une multiplication.
  • le champ « opérandes » indique la nature des données sur lesquelles l’opération désignée par le « code opération » doit être effectuée.

 

Les instructions machines sont relativement basiques (on parle d’instructions de bas niveau), voici quelques exemples :

  • les instructions arithmétiques (addition, soustraction, multiplication…).
    Par exemple, on peut avoir une instruction qui ressemble à « additionne la valeur contenue dans le registre R1 et le nombre 789 et range le résultat dans le registre R0 ».
  • les instructions de transfert de données qui permettent de transférer une donnée d’un registre du CPU vers la mémoire vive et vice versa.
    Par exemple, on peut avoir une instruction qui ressemble à « prendre la valeur située à l’adresse mémoire 487 et la placer dans la registre R2 » ou encore « prendre la valeur située dans le registre R1 et la placer à l’adresse mémoire 512 ».
  • les instructions de rupture de séquence : les instructions machines sont situées en mémoire vive dans l’ordre :
    Par exemple : si l’instruction n°1 est située à l’adresse mémoire 343, l’instruction n°2 sera située à l’adresse mémoire 344, l’instruction n°3 sera située à l’adresse mémoire 345…
    Au cours de l’exécution d’un programme, le CPU passe d’une instruction à une autre en passant d’une adresse mémoire à l’adresse mémoire immédiatement supérieure :
    Par exemple, après avoir exécuté l’instruction n°2 (situé à l’adresse mémoire 344), le CPU « va chercher » l’instruction suivante à l’adresse mémoire 344+1=345.
    Les instructions de rupture de séquence d’exécution encore appelées instructions de saut ou de branchement permettent d’interrompre l’ordre initial sous certaines conditions en passant à une instruction située une adresse mémoire donnée.
    Par exemple, dans le cas où à l’adresse mémoire 354 nous avons l’instruction suivante : « si la valeur contenue dans le registre R1 est strictement supérieure à 0 alors exécuter l’instruction située à l’adresse mémoire 4521 ».
    Si la valeur contenue dans le registre R1 est strictement supérieure à 0 alors la prochaine instruction à exécuter est l’adresse mémoire 4521, dans le contraire, la prochaine instruction à exécuter est à l’adresse mémoire 355.

 

Comme déjà dit, les opérandes désignent les données sur lesquelles le code opération de l’instruction doit être réalisée. Un opérande peut être de 3 natures différentes :

  1. l’opérande est une valeur immédiate : l’opération est effectuée directement sur la valeur donnée dans l’opérande
  2. l’opérande est un registre du CPU : l’opération est effectuée sur la valeur située dans un des registres (R0, R1, R2,…), l’opérande indique de quel registre il s’agit
  3. l’opérande est une donnée située en mémoire vive : l’opération est effectuée sur la valeur située en mémoire vive à l’adresse XXXXX. Cette adresse est indiquée dans l’opérande.

Exemples :

  • quand on considère l’instruction machine :
    « additionne le nombre 125 et la valeur située dans le registre R2 , range le résultat dans le registre R1 »
    nous avons 2 valeurs : « le nombre 125 » (qui est une valeur immédiate : cas n°1) et « la valeur située dans le registre R2 » (cas n°2)
  • quand on considère l’instruction machine :
    « prendre la valeur située dans le registre R1 et la placer à l’adresse mémoire 512 »
    nous avons 2 valeurs : « à l’adresse mémoire 512 » (cas n°3) et « la valeur située dans le registre R1 » (cas n°2)

 

Assembleur

Le microprocesseur étant incapable d’interpréter la phrase « additionne le nombre 125 et la valeur située dans le registre R2 , range le résultat dans le registre R1 », il faut coder cette instruction sous forme binaire :

« additionne le nombre 125 et la valeur située dans le registre R2 , range le résultat dans le registre R1 »

« 11100010100000100001000001111101 »

Afin de faciliter la lecture et l’écriture d’instructions machine par les informaticiens, on remplace les codes binaires par des symboles mnémoniques, en utilisant la syntaxe du langage appelé assembleur.

« additionne le nombre 125 et la valeur située dans le registre R2 , range le résultat dans le registre R1 »

« ADD R1,R2,#125 »

« 11100010 10000010 00010000 01111101 »

Remarque : chaque élément de l’instruction occupe une quantité de mémoire bien définie. Par exemple, en architecture ARM :

  • L’instruction ADD occupe les 12 bits de poids fort
  • Les adresses des registres R1 et R2 occupent chacune 4 bits
  • L’opérande #125 occupe les 12 bits de poids faible

Pour en savoir plus : Présentation Architecture et jeu d’instructions ARM

 

 

Exemples d’instructions en assembleur

Instructions Description
LDR R1,78
Place la valeur stockée à l’adresse mémoire 78 dans le registre R1
STR R3,125
Place la valeur stockée dans le registre R3 en mémoire vive à l’adresse 125
ADD R1,R0,#128
Additionne le nombre 128 (une valeur immédiate est identifiée grâce au symbole # ) et la valeur stockée dans le registre R0, place le résultat dans le registre R1
ADD R0,R1,R2
Additionne la valeur stockée dans le registre R1 et la valeur stockée dans le registre R2, place le résultat dans le registre R0
SUB R1,R0,#128
Soustrait le nombre 128 de la valeur stockée dans le registre R0, place le résultat dans le registre R1
SUB R0,R1,R2
Soustrait la valeur stockée dans le registre R2 de la valeur stockée dans le registre R1, place le résultat dans le registre R0
MOV R1, #23
Place le nombre 23 dans le registre R1
MOV R0, R3
Place la valeur stockée dans le registre R3 dans le registre R0
B 45
Structure de rupture de séquence : la prochaine instruction à exécuter se situe en mémoire vive à l’adresse 45
CMP R0, #23
Compare la valeur stockée dans le registre R0 et le nombre 23. Cette instruction CMP doit précéder une instruction de branchement conditionnel BEQ, BNE, BGT, BLT (voir ci-dessous)
CMP R0, R1
Compare la valeur stockée dans le registre R0 et la valeur stockée dans le registre R1.
CMP R0, #23
BEQ 78
La prochaine instruction à exécuter se situe à l’adresse mémoire 78 si la valeur stockée dans le registre R0 est égale à 23
CMP R0, #23
BNE 78
La prochaine instruction à exécuter se situe à l’adresse mémoire 78 si la valeur stockée dans le registre R0 n’est pas égale à 23
CMP R0, #23
BGT 78
La prochaine instruction à exécuter se situe à l’adresse mémoire 78 si la valeur stockée dans le registre R0 est plus grand que 23
CMP R0, #23
BLT 78
La prochaine instruction à exécuter se situe à l’adresse mémoire 78 si la valeur stockée dans le registre R0 est plus petit que 23
HALT
Arrête l’exécution du programme

 

Activité
Expliquer brièvement par une phrase, les instructions suivantes :
ADD R0, R1, #42
LDR R5,98
CMP R4, #18
BGT 77
STR R0,15
B 100
Écrire les instructions en assembleur correspondant aux phrases suivantes :
    • « Additionne la valeur stockée dans le registre R0 et la valeur stockée dans le registre R1, le résultat est stocké dans le registre R5 »
    • « Place la valeur stockée à l’adresse mémoire 878 dans le registre R0 »
    • « Place le contenu du registre R0 en mémoire vive à l’adresse 124 »
    • « la prochaine instruction à exécuter se situe en mémoire vive à l’adresse 478 »
    • « Si la valeur stockée dans le registre R0 est égale 42 alors la prochaine instruction à exécuter se situe à l’adresse mémoire 85 »

 

Labels

En réalité, les instructions assembleur B , BEQ , BNE , BGT  et BLT  n’utilisent pas directement l’adresse mémoire de la prochaine instruction à exécuter, mais des labels.

Un label correspond à une adresse en mémoire vive (c’est l’assembleur qui fera la traduction « label »→ »adresse mémoire »). L’utilisation d’un label évite donc d’avoir à manipuler des adresses mémoires.

Voici un exemple qui montre comment utiliser un label :

CMP R4, #18 
BGT monLabel 
MOV R0, #14 
HALT 
monLabel: 
MOV R0,#18 
HALT

 

Dans l’exemple ci-dessus, nous avons choisi monLabel  comme nom de label. La ligne MOV R0,#18  a pour label « monLabel » car elle est située juste après la ligne monLabel:.

Concrètement, voici ce qui se passe avec ce programme : si la valeur stockée dans le registre R4 est supérieure à 18 on place le nombre 18 dans le registre R0 sinon on place le nombre 14 dans le registre R0.

ATTENTION : la présence du HALT  juste après la ligne MOV R0,#14  est indispensable, car sinon, la ligne MOV R0,#18  sera aussi exécutée (même si la valeur stockée dans le registre R4 est inférieure à 18 )

Activité

Voici un programme Python très simple :

x = 4 
y = 8 
if x == 10: 
   y = 9 
else: 
   x = x+1 
z = 6

et voici maintenant voici son équivalent en assembleur :

MOV R0, #4 
STR R0,30 
MOV R0, #8 
STR R0,75 
LDR R0,30 
CMP R0, #10 
BNE else 
MOV R0, #9 
STR R0,75 
B endif 
else: 
LDR R0,30 
ADD R0, R0, #1 
STR R0,30 
endif: 
MOV R0, #6 
STR R0,23 
HALT
Après avoir analysé très attentivement le programme en assembleur ci-dessus, établir une correspondance entre les lignes du programme en Python et les lignes du programme en assembleur.
À quoi sert la ligne B endif  ?
À quoi correspondent les adresses mémoires 23, 75 et 30 ?

1 réponse

  1. Antoine Raby dit :

    Bonjour,
    Cherchant à construire une séquence (niveau 3e) sur les réseaux et leurs couches, je suis arrivé sur votre site. Il est très clair, lisible et bien mieux que tout ce que j’ai pu voir ailleurs.
    Je vais donc m’en inspiré pour construire ma séquence dont la problématique sera soulevé par une vidéo de 5 mn : Kaamelloot, les pigeons, où l’humour est basé sur l’imprécision des messages (pour qui ? , de qui ? , quand ?, les pigeons « sont nazes » ?)
    J’en ai profité pour découvrir quelques lignes en Assembleur ( quel boulot cela devait être !).
    Pour ma part, je code des pages web (HTML, CSS, MySQL, Javascript) et aussi en Arduino qui utilise soit Scratch soit une variante de C++.

    Très cordialement

    Antoine Raby

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *