John Von Neumann (1903-1957) a donné son nom à la "machine de Von Neumann". Cette architecture de Von Neumann est encore utilisée dans la quasi-totalité des ordinateurs actuels, voici pour commencer une version simplifiée de cette machine.
Registre A : registre accumulateur (permet de "ranger" une valeur avant de l'utiliser)
Registre RI : registre instruction (l'instruction en cours est stockée dans ce registre)
Registre CO : (compteur ordinal) pointe en début d'instruction sur l'instruction que l'on veut traiter
Mémoire (RAM) : mémoire adressable (instructions et données sont "rangées" dans la mémoire. Chaque instruction ou donnée "possède" une adresse qui permet de repérer sa position en mémoire)
RADM : registre d'adresses mémoires (contient des "adresses mémoires")
Le langage machine (binaire) est le seul langage "compris" par la machine, mais il est trop difficile à lire pour un humain (exemple d'une instruction : 10010010000111000101). Une amélioration très importante est de donner aux différentes instructions une représentation symbolique (ADD #3 est plus facile à lire et à comprendre que 0001000000000011 pourtant les 2 ont la même signification).
LDA : a pour but de mettre une donnée dans le registre A dont l'adresse ou la valeur est donnée en paramètre
ADD : additionne la donnée dont l'adresse ou la valeur est donnée en paramètre à la valeur contenue dans A
STA : permet de sauvegarder en mémoire (RAM) à l'adresse donnée en paramètre le contenu du registre A
BRA : permet de rompre l'ordre d'exécution séquentiel (ligne après ligne) des instructions en se "branchant" à l'instruction dont l'adresse est donnée en paramètre.
BRZ : permet de rompre la séquence de façon conditionnelle au contenu du registre A : si on trouve la valeur 0 dans le registre A=>l'instruction suivante est celle indiquée par le paramètre. Autrement, le programme suit son cours normal.
adressage immédiat : LDA #3=>charge la valeur 3 dans le registre A
adressage direct : LDA 100=>charge dans A la valeur contenue en mémoire à l'adresse 100
Voyons comment la machine de Von Neumann gère une suite d'instruction :
Etat 1
CO : 150
RADM : ???
Mémoire :
RI : LDA#3
A : ???
Explication : CO : 150 => La prochaine instruction à lire se trouve en mémoire à l'adresse 150 (c'est un exemple) ; RI : LDA#3 => On a placé LDA#3 dans RI
Etat 2
CO : 150
RADM : ???
Mémoire :
RI : LDA#3
A : 3
Explication : A : 3 => On a "rangé" la valeur 3 dans le registre A
On passe maintenant à l'instruction suivante CO=CO+1 => CO : 151
Etat 3
CO : 151
RADM : ???
Mémoire :
RI : STA 201
A : 3
Explication : on a chargé l'instruction suivante (STA 201) dans le registre d'instruction
Etat 4
CO : 151
RADM : ???
Mémoire :
RI : STA 201
A : 3
Explication : On a "rangé" la valeur contenue dans le registre A (3) en mémoire (à l'adresse 201) et on passe à l'instruction suivante CO=CO+1 : on aura donc ensuite CO : 152
Etat 5
CO : 152
RADM : ???
Mémoire :
RI : BRA 576
A : 3
Explication : Nous avons ici un saut ( rupture de l'ordre d'exécution séquentiel), le compteur cardinal pointe maintenant sur l'instruction située à l'adresse 576 (la prochaine instruction exécutée sera donc LDA 343)
.....
voici un programme en Python
x=3
y=5
z=x+y
et en assembleur cela donne quoi ?
Nous pouvons définir des variables x, y et z qui sont associées à des adresses en mémoire (une variable correspond à une adresse en mémoire, par exemple on associe x à la case mémoire d'adresse 121).
NB : la partie du code permettant d'associer les variables x, y et z à des "cases" mémoire n'est pas donnée ici (par souci de ne pas trop compliquer les choses)
LDA #3
STA x
LDA #5
STA y
LDA x
ADD y
STA z
Il existe différents langages qui permettent de programmer un ordinateur, mais le seul directement utilisable par le processeur est, comme nous venons de le voir, le langage machine (suite de 0 et de 1)
Vous connaissez déjà quelques langages de haut niveau (au moins le Python et le JavaScript, mais il en existe beaucoup d'autres : C, C++, Java.....).
Les instructions, une fois écrites par le programmeur, sont forcément « traduites » en langage machine.
Un programme spécialisé assure cette traduction. Ce système de traduction s'appellera interpréteur ou bien compilateur, suivant la méthode utilisée pour effectuer la traduction.
En simplifiant à l'extrême, l'interpréteur assure une traduction "à la volée" des instructions. (une ligne est traduite en langage machine puis immédiatement exécutée).
La compilation traduit l'ensemble des instructions en langage machine. Une fois cette traduction assurée, il est alors possible d'exécuter le programme (le fameux .exe sous windows). C et C++ sont des langages compilés.
Les langages compilés sont réputés plus rapides à l'exécution que les langages interprétés. En revanche, il faut savoir que la compilation peut prendre beaucoup de temps (pour de gros programmes) et à chaque modification du code source (code source : suite d'instruction écrite par le programmeur), une nouvelle compilation est nécessaire.
Il existe une troisième voie qui a le vent en poupe : le code source est compilé en pseudocode (appelé bytecode) qui n'est pas encore du langage machine, mais s'en rapproche par rapport au code source de départ. Ce bytecode est ensuite interprété (l'interprétation est beaucoup plus rapide que pour des langages 100% interprétés). Beaucoup de langages dit "modernes" utilisent ce système de bytecode : Python, Java, JavaScript.....(tous ces langages n'utilisent pas le même système d'interprétation du bytecode, par exemple Java utilise une machine virtuelle pour effectuer cette interprétation).
En fait le système est un peu plus complexe
Le bus permet aux impulsions électriques (représentées par des 0 et des 1) de "voyager" entre les différentes parties du système.
Les multiplexeurs (MUX1 et MUX2 sur le schéma) sont en quelque sorte des aiguillages. Par exemple, en fonction de l'état de MUX1 (état commandé par un quatrième "fil" non représenté sur le schéma), nous retrouvons en sortie de MUX1 les informations en provenance du registre CO ou du registre RADM.
L'unité arithmétique et logique (UAL) peut, selon son état, présenter à sa sortie :
Chacun de ces systèmes est composé de nombreuses portes logiques qui assurent les fonctions décrites ci-dessus.
Vous devez aussi savoir que tout ce beau monde doit fonctionner de concert. Le chef d'orchestre est un système d'horloge qui donne des "tops" régulièrement, à chaque top, les différents composants sont "autorisés" à changer d'état. En simplifiant, un micro processeur à 2 GHz possède une horloge qui donne 2 milliards de tops par seconde !
Pour terminer, et ici encore en simplifiant énormément, chaque instruction en langage machine va électriquement parlant agir sur les portes logiques et ainsi modifier l'état du système à chaque top d'horloge.
Et avec tout cela, on arrive à "fabriquer" des jeux vidéos et bien d'autres choses