Archi M10

Identification

Infoforall

1 - Un vrai ordinateur en papier


Bon, alors, c'est quoi un ordinateur ?

Et bien, c'est à cette question que nous allons répondre aujourd'hui.

Cette activité est basée en grande partie sur le travail de Philippe Marquet et Martin Quinson. Nous l'utiliserons à nouveau en Terminale et nous irons alors plus loin. Source : M10 / M999 disponible ici sous la licence CC-BY 4.0.

Evaluation ✎ : questions 3-4.

Documents de cours :

1 - Un peu d'histoire

De quand date le premier ordinateur de l'histoire ?

Tout dépend de ce qu'on considère être un ordinateur.

1.1 Le premier ordinateur de l'Histoire ?

L'idée

En 1834, le mathématicien anglais Charles Babbage fut l'un des précurseurs de l'informatique.

https://commons.wikimedia.org/wiki/File:Charles_Babbage_-_1860.jpg
Charles Babbage - Image du domaine public USA

Son idée était de produire des tables nautiques, astronomiques et mathématiques exactes : à l'époque, les tables sont écrites ou tapées à la main et comportent donc des erreurs de recopies ou de calculs.

La machine mécanique

Babagge fut le premier à énoncer le principe d'un ordinateur. Il s'est inspiré de la machine à tisser Jacquard (inventées en 1801 par le lyonnais Joseph Marie Jacquard) qui utilise des cartes perforées pour encoder les informations.

https://commons.wikimedia.org/wiki/File:Jacquard_loom_p1040320.jpg
Métier Jacquard Musée des Arts et Métiers [CC BY-SA]

Partant de ce principe, Charles Babbage imagine un calculateur mécanique qui recevrait instructions et données à partir de la lecture des perforations sur les fiches.

Données et instructions sur des cartes un peu différentes
Les instructions sont sur les cartes du premier plan et les données à l'arrière plan.
Cette image, publiée initialement sur Flickr, a été stockée sur WikiCommons avec Flickr upload bot le 20 Octobre 2010, 14:34 par Liftarn. Cette image est sous licence [CC BY-SA]

Il passa le reste de sa vie à travailler sur les détails de cette machine analytique, tentant de la faire fonctionner... sans succès.

Modèle d'essai d'une partie de la machine analytique, construit par Charles Babbage, exposée au Science Museum de Londres.
Une partie de la machine analytique, construit par Charles Babbage, exposée au Science Museum de Londres.
Musée des Arts et Métiers (photo Bruno Barral) [CC BY-SA]
Un échec ?

Même s'il ne parvint pas à la construire de son vivant, elle n'a été réellement opérationnelle qu'en 1991 (avec l'équivalent des technologies d'époque) lorsque des universitaires ont cherché à la construire à l'aide des plans de Baggage. Avec un peu plus de chance (il avait commis quelques petites erreurs de conception), il aurait pu réussir à construire sa machine. La théorie était bonne et fonctionnelle.

L'Histoire aurait sans doute été bien différente si la machine avait vu le jour. La Machine à différences, un roman de science-fiction est construit autour de cette uchronie : que ce serait-il passé si Charles Babbage était parvenu à faire fonctionner sa machine analytique ?

Couverture La machine à différences J'ai Lu
Couverture de la Machine à Différences de William Gibson et Bruce Sterling
1.2 Le premier programme de l'Histoire ?

Pendant ces nombreuses années de recherche, Charles Babbage entre en contact avec de nombreuses personnes.

Parmi elles figure Ada Lovelace, de son nom complet Augusta Ada King, comtesse de Lovelace, née Ada Byron. Il s'agit de la fille du poète Lord Byron, un poète anglais très connu.

Elle ne connut pas son père puisqu'il quitta l'Angleterre pour toujours alors qu'elle n'avait qu'un an. Sa mère demanda la séparation et la garde de l'enfant : Byron était régulièrement saoul, violent et tenta au moins par quatre fois de la violer. Encore un exemple de la différence entre image publique et réalité de l'individu...

Eduquée par sa mère, elle-même cultivée et intelligente, Ada Lovelace parvient à devenir une jeune fille particulièrement douée et éduquée en mathématiques, ce qui est très inhabituel à l'époque : la maîtrise des sciences étant un symbole de puissance et de contrôle, on écartait les femmes de cette connaissance. A l'heure actuelle, les raisons sont plus indirectes mais lorsqu'on fouille, on trouve encore les mêmes causes...

.

Lors de ses premières correspondances avec Charles Babbage, elle est à l'époque une jeune fille de 17 ans.

Ada Lovelace
Ada Lovelace, née Ada Byron

Ada Lovelace est immédiatement fascinée par la machine théorique de Charles Babbage. Même après son mariage, elle continuera ses études de mathématiques, parvenant même à obtenir comme tuteur le célèbre mathématicien Auguste De Morgan.

Elle étudiera la machine avec passion et parviendra à créer le premier programme de l'histoire ! En collaboration avec Charles Babbage, elle mettra au point un algorithme permettant de lancer un calcul très complexe sur la machine.

Elle est aujourd'hui considérée comme la première programmeuse de l'histoire. Aucun humain avant elle n'avait conçu de programme potentiellement exécutable sur une machine réelle. Son programme comportait d'ailleurs la première boucle non bornée (TANT QUE) non purement théorique de l'histoire.

Une autre idée révolutionnaire qu'on lui attribue : l'idée d'encoder autre chose que des nombres avec des nombres ! Maintenant que vous avez vu qu'on pouvait encoder un texte, une image ou une relation à l'aide d'une suite de nombres, cela vous parait peut-être évident, mais comme toujours, tant que personne n'en a eu l'idée, une invention n'existe pas. Elle aurait ainsi eu l'idée d'utiliser la machine pour créer des morceaux de musique.

Alternant entre haut et bas, elle tentera de créer des algorithmes permettant de gagner aux courses hippiques (pour subventionner la machine !) mais dilapida malheureusement son argent. Elle mourut jeune, à l'age de 36 ans. Encore une fois, l'histoire aurait (peut-être) pu être différente sinon.

Voici une illustration de son programme : image du programme (Cette œuvre est dans le domaine public dans tous les pays pour lesquels le copyright a une durée de vie de 100 ans ou moins après la mort de l'auteur).

Pour l'anecdote, on peut voir son portrait sur les hologrammes d'authentification des produits Microsoft (les vieux produits, ceux où il y avait encore une trace papier de l'acquisition du produit !).

C'est comment la France de 1830 ?

La France est dans un état politique assez instable à cette époque.

  • Après la Révolution Française de 1789,
  • le coup d'Etat du 18 brumaire de Napoléon Bonaparte (début du Consulat),
  • la création du Premier Empire en 1804,
  • l'abdication de Napoléon en 1814, le retour de Napoléon et les Cent-Jours en 1815,
  • la Seconde Restauration (monarchie conservatrice) de 1815 à 1830 (Louis XVIII puis son frère Charles X),
  • la seconde révolution de 1830 avec la Monarchie de Juillet et le régime de Louis-Philippe Ier (une Monarchie constitutionnelle à régime parlementaire)

Cette période est complexe, pleine de complots, d'insurrections et de manipulations politiques. Elle aboutit à l'instauration de la IIe République, une période plus que troublée également !

2 - Présentation M10

Aujourd'hui, nous allons vous offrir un ordinateur. Un vrai. Mais en papier.

2.1 La machine M10 : version 1

M-10 est une petite machine informatique constituée

  • d'une mémoire centrale ("RAM") qui contient des données (les 10 cases à droite),
  • d'un processeur qui contient 
    • une unité arithmétique et logique (UAL) capable de réaliser une opération telle une addition,
    • une petite mémoire nommée registre qui porte ici le nom d'accumulateur car ce registre recevra le résultat des opérations réalisées par l'UAL.

Les 10 cases de la mémoire centrale ("RAM") sont numérotées de 0 à 9, l'adresse de la case.

La communication UAL-registre est rapide puisque l'UAL et le registre font partie du même composant : le processeur.

La communication UAL-RAM est longue.

La communication UAL-disque dur (non représenté ici) est encore plus longue.

https://gitlab-fil.univ-lille.fr/diu-eil-lil/portail/raw/master/bloc3/archi/m10-0.png
La structure de la machine M10

2.2 Les premières instructions sur M10

Adressage des registres et des cases de la mémoire centrale.

L'adresse d'un registre commence par R fait référence à un registre.

  • RA pour le registre A, A comme accumulateur.
  • RB pour le registre B.
  • RC pour le registre C.
  • ...

L'adresse d'une case de RAM commence par @.

  • @0 pour la case 0.
  • ...
  • @9 pour la case 9.
Jeux d'instructions de transfert

Ces instructions transportent les informations d'une mémoire à une autre.

Une instruction MOV DST SRC place le contenu de la source SRC dans la destination DST.

C'est équivalent à DST <-- SRC.

  • DST peut être un registre ou une case de la RAM.
  • SRC peut être un registre, une case de la RAM ou une vraie valeur.

Exemples :

  • MOV RA #3        RA <-- 3, place la valeur 3 dans le registre RA.
  • MOV RA @3        RA <-- @3, place le contenu de la case 3 de la mémoire centrale dans le registre RA.
  • MOV @3 RA        @3 <-- RA, place le contenu du registre RA dans la case 3 de la mémoire centrale
  • MOV RA RB        RA <-- RB, place le contenu du registre RB dans le registre RA.

Cas particulier : les crochets indiquent d'aller lire le contenu de la case mémoire dont l'adresse est contenue dans un registre :

  • MOV RA #1 : on place 1 dans le registre RA.
  • MOV RB [RA] est alors équivalent à MOV RB @1.
Jeux d'instructions arithmétiques et logiques

Ce sont les instructions (+, , -, *, ET, OU ... ) toutes réalisées par l'UAL.

Instruction ADD

ADD YY XX revient à faire RA <-- YY + XX dans notre M10.

YY XX peuvent être des registres, des cases-mémoires ou des valeurs.

Exemples :

  • ADD @1 @3        est équivalent à RA <-- @1 + @3.
  • ADD @2 #5        est équivalent à RA <-- @2 + 5.

Instruction SUB

SUB YY XX revient à faire RA <-- YY - XX dans M10.

YY XX peuvent être des registres, des cases-mémoires ou des valeurs.

Exemples :

  • SUB @5 #3        est équivalent à RA <-- @5 - 3.
Un tout petit rikiki programme

Imaginons que la mémoire centrale contienne ceci :

Adresse RAM 00 01 02
Valeur      05 15 30

Addition avec 5 à @0, 15 à @1 et 30 à @2

Voici un programme dans lequel RA indique l'Accumulateur :

ADD @0 @2    ---> l'UAL calcule (5+30) et place 35 dans RA
MOV @0 RA    ---> on déplace le contenu 35 de RA vers la case 0.

01° Que contient la mémoire centrale après exécution du programme ?

La mémoire centrale initialement :

Adresse 00 01 02
Valeur  05 15 30

Le programme :

ADD @1 @2

MOV @1 RA

...CORRECTION...

ADD @1 @2

Equivalent Python de RA = @1 + @2 : on additionne 15 et 30 et on place 45 dans le registre RA.

Addition avec 5 à @0, 15 à @1 et 30 à @2

La dernière ligne va alors écrasé le 15 de la case 1 pour y placer 45.

02° Exécuter le programme suivant en utilisant la mémoire initiale représentée ci-dessous.

  • Que contiennent les mémoires à la fin ?
  • Traduire les lignes 1-2 par une ligne de code Python, en attribuant les variables a b c d e f aux cases-mémoires 0 à 5.
  • Adresse 0 1 2 3 4 5
    Nommée  a b c d e f

  • Faire de même avec les lignes 3-4.
Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(15)-@2(30)-@3(50)
01 ADD @2 @3 02 MOV @4 RA 03 ADD @3 @4 04 MOV @5 RA

...CORRECTION...

  1. ADD @2 @3 : on additionne 30 et 50 et on place 80 dans RA
  2. MOV @4 RA : on range ce 80 dans la case d'adresse 4.
  3. Addition avec 5 à @0, 15 à @1 et 30 à @2

Ces lignes pourraient être l'équivalent de cette unique ligne en Python :

e = c + d

On passe aux instructions suivantes :

  1. ADD @3 @4 : on additionne 50 et 80 et on place 130 dans RA
  2. MOV @5 RA : on range ce 130 dans la case d'adresse 5.
  3. Addition avec 5 à @0, 15 à @1 et 30 à @2

Ces lignes pourraient être l'équivalent à cette ligne Python :

f = d + e

03° Exécuter le programme suivant en utilisant la mémoire initiale représentée ci-dessous.

Questions :

  1. Que contiennent les mémoires à la fin ?
  2. Quelle serait l'unique ligne équivalente Python (a est la case 0 et b la case 1) 
Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(1)
SUB @0 @1 MOV @0 RA SUB @0 @1 MOV @0 RA SUB @0 @1 MOV @0 RA

...CORRECTION...

Ces lignes pourrait être l'équivalent de a = a - 3 * b en Python.

Le problème est que l'accès à la RAM (mémoire centrale) est lent.

Or, comme nous n'avons qu'un seul registre, nous sommes obligés de faire constamment travailler l'UAL à partir des données stockées en RAM. Nous utilisons donc souvent les liaisons rouges.

Nous allons tenter de régler ce problème en rajoutant des registres : nous allons pouvoir stocker les données nécessaires dans les registres et faire tous les calculs en utilisant ces registres. Une fois le calcul terminé, nous placerons le résultat final en RAM.

✎ 04° Exécuter ce nouveau programme qui tourne sur une version plus complexe de M10 : elle intègre maintenant 3 registres supplémentaires RB RC et RD.

  • En rouge, les transferts longs ;
  • En bleu, les transferts rapides.

Questions

  1. Que contiennent les cases-mémoires de la RAM à la fin ?
  2. Pourquoi ce nouveau programme est-il plus rapide ?
Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(1)
MOV RA @0 MOV RB @1 SUB RA RB SUB RA RB SUB RA RB MOV @0 RA
2.3 La machine M10 : version 2

Description finale de notre M10

M-10 est une petite machine informatique constituée

  • d'une mémoire centrale ("RAM") qui contient des données (les 10 cases à droite),
  • d'un processeur qui contient 
    • une unité arithmétique et logique (UAL) capable de réaliser une opération telle une addition,
    • de petites mémoires nommées registres :
      • un registre RA ou EAX, l'Accumulateur qui récupèrera parfois, voir la remarque sur l'évolution, les résultats de l'UAL ;
      • un registre RB ou EBX, le registre Basique ;
      • un registre RC ou ECX, le registre Compteur/Counter ;
      • un registre RD ou EDX, le registre de Données/Data ;.
      • Leur rôle n'est pas imposé en réalité mais on utilisera plutôt celui dont le nom convient le mieux par habitude. Ils sont interchangeables en réalité.

Les 10 cases de la mémoire centrale ("RAM") sont numérotées de 0 à 9, l'adresse de la case.

La communication UAL-registre est rapide puisque l'UAL et le registre font partie du même composant : le processeur.

La communication UAL-RAM est longue.

La communication UAL-disque dur (non représenté ici) est encore plus longue.

Résultat de l'UAL

Historiquement, dans les premiers processeurs, l'UAL fournissait toujours le résultat dans RA.

C'est pour cela que notre petite M10 v1 opérait ainsi.

C'est plus compliqué dans les processeurs modernes réels mais cela dépend du modèle.

A partir de maintenant, on considère que ADD et SUB fonctionnent ainsi :

  • Si le premier paramètre est un registre, ADD RX YY est équivalente à RX <-- RX + YY.
  • Si le premier paramètre n'est pas un registre, ADD XX YY est équivalente à RA <-- XX + YY, comme avant.
  • Si le premier paramètre est un registre, SUB RX YY est équivalente à RX <-- RX - YY.
  • Si le premier paramètre n'est pas un registre, SUB XX YY est équivalente à RA <-- XX - YY, comme avant.

Le registre RA est donc juste une sorte de registre par défaut pour le résultat.

Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(1)
La structure de la machine M10

Comme vous le voyez sur le schéma, l'UAL peut désormais fournir son résultat à RA mais également aux autres registres. Tout dépend de la nature du premier paramètre : registre, ou pas ?

✎ 05° Exécuter ce nouveau programme qui tourne sur la dernière version de M10, celle où ce n'est pas nécessairement RA qui récupère le résultat.

Questions

  1. Que contiennent les cases-mémoires de la RAM à la fin ?
  2. Pourriez-vous créer un programme Python équivalent ?
Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(1)
MOV RA @0 MOV RB @1 SUB RB RA ADD RB RB MOV RC @2 ADD RC RB MOV @0 RC
2.5 Assembleur

Langage machine

Le langage machine est constitué des octets reçus par le processeur.

Chaque suite d'octets correspond à une instruction qu'on veut voir exécuter par l'UAL.

Assembleur ?

Le mot "Assembleur" est ambiguë car on peut en réalité parler de deux choses :

  • Soit du langage d'assemblage : c'est le langage que vous utilisez sur cette activité ;
  • Soit du programme assembleur ; c'est le programme qui reçoit le code-texte que vous avez produit et qui le traduit en langage machine (une suite de 0 et de 1).
  • Langage d'assemblage (texte)  ⇒   Programme Assembleur   ⇒  Langage machine (binaire)
    "ADD RA RB"  0000 1111 0000 0001 0000 0010 
Langage machine M10 : gestion des adresses

Sur M10 l'encodage des nombres, des adresses des registres, et des adresses des cases de RAM est toujours sur 8 bits et suit ce principe : l'interprétation dépend des deux premiers bits.

  • 00 pour un registre : le registre 2 (RB en assembleur M10) s'écrit ainsi en langage machine M10 :
    0000 0010     puisque les 6 bits suivants 00 0010 code 2 en binaire
  • 01 pour la RAM : la case 2 en RAM (@2 en assembleur M10) s'écrit ainsi en langage machine M10 :
    0100 0010
  • 11 pour un entier : l'entier 2 en RAM (#2 en assembleur M10) s'écrit ainsi en langage machine M10 :
    1100 0010
Langage machine M10 : gestion des instructions

En langage machine M10, une instruction est encodée sur 8 bits également.

Donnons deux exemples :

  • Addition entre deux registres :  0000 1111 
  • Considérons cette instruction en langage machine M10 :

     0000 1111 0000 0001 0000 0010 

    • Les 8 premier bits  0000 1111  correspondent en M10 à l'addition des contenus de deux registres ;
    • La machine sait donc maintenant qu'elle a besoin des deux adresses de registres ;
    • Les 8 bits suivants  0000 0001  correspondent au registre numéro 1, c'est à dire RA ;
    • Les 8 bits suivants  0000 0010  correspondent au registre 2, c'est à dire RB ;

    Cette instruction langage machine se traduit par ADD RA RB en assembleur M10.

  • Addition entre un registre et un nombre :  0000 1010 
  • Considérons cette instruction en langage machine M10 :

     0000 1010 0000 0001 1100 0010 

    • Les 8 premier bits  0000 1010  correspondent en M10 à l'addition d'un registre et d'un entier ;
    • La machine sait donc maintenant qu'elle a besoin d'un registre et d'un entier ;
    • Les 8 bits suivants  0000 0100  correspondent au registre numéro 4, c'est à dire RD ;
    • Les 8 bits suivants  1100 0111  correspondent à l'entier 7, c'est à dire #7 ;

    Cette instruction langage machine se traduit par ADD RA #7 en assembleur M10.

La différence est donc mince entre langage machine et langage d'assemblage. Pourquoi ?

Si on tape ADD, le programme assembleur va chercher les textes des deux adresses derrière pour savoir quelle version de ADD on veut réaliser. S'il détecte deux registres, il transforme notre texte ADD en  0000 1111 .

Il lui reste alors à traduire RA et RB en  0000 0001  et  0000 0010 .

Avec le langage d'assemblage et le programme assembleur, tout le monde est content :

  • L'humain décrit ce qu'il veut faire en partie avec des mots clés.
  • Le processeur reçoit bien l'instruction en langage machine, le seul qu'il peut utiliser.
Un seul langage d'assemblage ?

En assembleur, chaque famille de processeurs a son propre langage d'assemblage puisque chaque instruction doit réellement correspondre aux suites de bits que cette puce peut comprendre.

Langage d'assemblage M10(texte)  ⇒   Programme Assembleur M10   ⇒  Langage machine M10 (binaire)
"ADD RA RB"  0000 1111 0000 0001 0000 0010 

On dit que l'assembleur est un langage bas niveau : pour programmer, il faut savoir exactement quels sont les éléments présents. Quel processeur ? Quelle RAM ? ...

Un programme réalisé pour un processeur particulier ne pourra pas surement pas s'exécuter sur un processeur d'une autre famille :

Désavantage : limité à un type de processeur.

Avantage : très rapide.

✎ 06° Exécuter ce nouveau programme qui tourne sur la dernière version de M10, celle où ce n'est pas nécessairement RA qui récupère le résultat.

Voici quelques instructions en langage machine M10 qui ont besoin de 2 paramètres qu'on nommera X et Y :

  • 0000 1111 : addition entre deux registres : RX <- RX + RY
  • 0000 1110 : addition entre un registre et une case de RAM: RX <- RX + @Y
  • 0000 1010 : addition entre un registre et un nombre : RX <- RX + #Y
  • 0000 1100 : addition entre deux cases de RAM : RA <- @X + @Y
  • 1100 1111 : déplacement d'un registre dans un autre registre: RX <- RY
  • 1100 1110 : déplacement d'une case de RAM dans un registre: RX <- @Y
  • 1100 1101 : déplacement d'un registre vers une case de RAM : @X <- RY
  • 1100 1110 : déplacement d'un nombre vers un registre: RX <- #Y

Questions

  1. Que contiennent les cases-mémoires de la RAM à la fin ?
  2. Quel est le programme équivalent en assembleur ?
  3. Quel est le programme équivalent en Python (la variable a est la case 0 ect...) ?
1100 1110 0000 0011 0100 0010 1100 1110 0000 0010 0100 0011 0000 1111 0000 0011 0000 0010 0000 1010 0000 0011 1100 0100 1100 1101 0100 0010 0000 0011
Enoncé de l'exerice : les mémoires contiennent @0(5)-@1(1)

...CORRECTION...

On fournit toutes les explications. Votre version doit être plus synthétique.

1er ligne

1100 1110 0000 0011 0100 0010

1100 1110 : déplacement d'une case de RAM dans un registre : RX <- @Y

0000 0011 : 00, c'est bien un registe, 00 0011 : c'est le registre 3 : RC.

0100 0010 : 01, c'est bien une case de RAM, 00 0010 : c'est la case 2, qui contient la valeur 3.

Cette suite de bits est donc équivalente à MOV RC @2 en assembleur M10.

RC contient donc maintenant 3.

2e ligne

1100 1110 0000 0010 0100 0011

1100 1110 : déplacement d'une case de RAM dans un registre : RX <- @Y

0000 0010 : 00, c'est bien un registe, 00 0010 : c'est le registre 2 : RB.

0100 0011 : 01, c'est bien une case de RAM, 00 0011 : c'est la case 3, qui contient 6.

Cette suite de bits est donc équivalente à MOV RB @3 en assembleur M10.

RB contient donc maintenant 6.

3e ligne

0000 1111 0000 0011 0000 0010

0000 1111 : addition entre deux registres : RX <- RX + RY

0000 0011 : 00, c'est bien un registe, 00 0011 : c'est le registre 3 : RC.

0000 0010 : 00, c'est bien un registe, 00 0010 : c'est le registre 2 : RB.

Cette suite de bits est donc équivalente à ADD RC RB en assembleur M10.

RC contient donc maintenant 6+3 = 9.

4e ligne

0000 1010 0000 0011 1100 0100

0000 1010 : addition entre un registre et un nombre : RX <- RX + #Y

0000 0011 : 00, c'est bien un registe, 00 0011 : c'est le registre 3 : RC.

1100 0100 : 11, c'est bien un nombre, 00 0100 : c'est l'entier 4 : #4.

Cette suite de bits est donc équivalente à ADD RC #4 en assembleur M10.

RC contient donc maintenant 9+4 = 11.

5e ligne

1100 1101 0100 0010 0000 0011

1100 1101 : déplacement d'un registre vers une case de RAM : @X <- RY

0100 0010 : 01, c'est bien une case de RAM, 00 0010 : c'est la case 2 : @2.

0000 0011 : 00, c'est bien un registre, 00 0011 : c'est le registre 3 : RC.

Cette suite de bits est donc équivalente à MOV @2 RC en assembleur M10.

La case de la RAM 2 contient maintenant 11.

Si on résume, cela donne ceci en assembleur M10 :

MOV RC @2 MOV RB @3 ADD RC RB ADD RC #4 MOV @2 RC

En code Python équivalent, on considèrera que la case 0 est la variable a, la case 2 la variable b, la case 3 la variable c et la case 4 la variable d.

L'état de la mémoire est donc définie dès le départ : c contient 3 et d contient 6.

La seule case de RAM qu'on ramène en mémoire est donc la case 2 (voir la dernière ligne d'assembleur.

Cela correspond donc juste à une ligne Python qui pourrait être :

c = c + d + 4

✎ 07° Réaliser le programme en langage machine M10 qui permettrait de faire cela, c'est à dire créer 3 variables (la variable a est la case RAM 0 ect...) :

a = 10 b = 6 c = a + b

Attention, pour réaliser l'initialisation des variables, il faut nécessairement commencer par remplir un registre avec la bonne valeur puis transférer ce registre vers la bonne case de la RAM.

...CORRECTION...

On fournit toutes les explications. Votre version doit être plus synthétique.

Si on résume, cela pourrait donner ceci en assembleur M10, chaque ligne vide indique qu'on passe à l'instruction Python suivante :

MOV RA #10 RA contient 10 MOV @0 RA a ou @0 contient 10 MOV RB #6 RB contient 6 MOV @1 RB b ou @1 contient 6 ADD RA RB on additionne dans RA les valeurs de RA et RB MOV @2 RA c ou @2 contient 16

Attention, il existe plusieurs variantes possibles. Rien ne vous oblige à prendre les mêmes registres par exemple. Notez bien que ADD RA RB modifie RA, pas la variable a stockée dans @0.

Reste à faire le plus pénible : le code machine...

1100 1110 0000 0001 1100 1010 1100 1101 0100 0000 0000 0001 1100 1110 0000 0010 1100 0110 1100 1101 0100 0001 0000 0010 0000 1111 0000 0001 0000 0010 1100 1101 0100 0010 0000 0001
2.6 Les vrais assembleurs

Dans les architectures load-store, les programmes

  1. transfèrent d'abord des données de la mémoire centrale/RAM (lente mais grand stockage) vers des registres (rapide mais faible stockage) avec LDR
  2. puis effectuent des opérations directement sur ces registres, et
  3. enfin transfèrent le résultat des registres vers la RAM avec LDR dans l'autre sens.
les différents types de mémoire
Par Original téléversé par Poil sur Wikipédia français. — Auteur : Stéphane 3 avr 2005 à 03:54 (CEST)Source PPT disponible sur demande., CC BY-SA 3.0, Lien

Il existe plusieurs zones de stockage différentes :

  • Registres : les petites mémoires proches du processeur. Rapides mais petites. A connaître
  • Caches on-chip et caches off-chip : des zones mémoires assez rapides situées près de la sortie de la puce (chip) qui contient le microprocesseur. On y stocke temporairement des résultats lorsqu'on veut faire des transferts registres-RAM.
  • Mémoire centrale : une mémoire bien plus grande mais également beaucoup plus longue en terme d'accés (RAM). A connaître.
  • Système de stockage de masse : disque dur, clé USB... Encore plus grande mais encore plus lente.
  • Système d'archivage : des bandes magnétiques, très gros espace mais leeeeeent.
2.7 Remarque finale : les vrais assembleurs

On type les instruction ou on type les données, pas les deux

Notre version d'assembleur M10 est en réalité très redondant : le type de ADD ou de MOV indique sur quoi on devrait agir et les données à manipuler contiennent également un moyen de savoir s'il s'agit d'un registre, d'une case de RAM ou d'un nombre.

Dans la réalité, les langages d'assemblage utilisent l'une ou l'autre des possibilités :

  • Dans certaines versions, c'est l'instruction qui porte le type attendu des paramètres : on dit ADD_REGISTERS et cela implique que les deux identifiants qui suivent seront lus comme des identifiants de registres.
  • Dans certaines versions, l'instruction ADD indique juste qu'on va additionner les deux choses qui vont suivre. Dans ce cas, les identifiants doivent contenir de quoi savoir si c'est un registre, une case de RAM ou un nombre...

C'est pour cela que je présente les deux façons de faire dans M10 mais sachez qu'on utilise soit l'une soit l'autre pour des raisons de rapidité.

Taille des données

De la même façon, dans un vrai langage d'assemblage, il existe des données sur 8 bits, sur 16 bits, sur 32 bits... On doit donc indiquer la largeur des données qu'on désire manipuler.

Et plus encore

Enfin, il existe de quoi générer des labels pour obtenir des sortes de variables, on peut indiquer de repartir sur telle ou telle ligne pour réaliser des boucles...

CONCLUSION : ce qui vous venez de voir vous a permis de comprendre ce qu'est l'assembleur et le langage machine, mais il faut avoir conscience qu'il ne s'agissait que d'une introduction.

Il reste toujours pas mal de questions en suspens. Quatre exemples :

  1. Où sont stockés les programmes là-dedans ?
  2. Comment fait la machine pour réaliser une addition concrètement ?
  3. Comment récuper des données externes (clavier ?) ?
  4. Comment envoyer des données vers l'extérieur (écran ?) ?

3 - Machine de Turing

3.1 Algorithme

Pendant très longtemps, la notion d'algorithme a été une notion floue. On le définissait comme un nombre fini d'instructions menant à un résultat sur certaines entrées, instructions opérées sur une "machine".

Or, on n'avait pas de défintion mathématique de ce qu'était une machine. Sans cette définition, pas de possibilité de faire des démonstrations et des théorèmes sur les algorithmes : pour travailler, les mathématiques ont besoin d'une définition mathématique de l'objet qu'elle étudie.

3.2 Le créateur de l'informatique théorique ?

Alan Turing

Alan Turing (1912-1954) est un mathématicien et cryptologue britannique. Nous allons voir que ses recherches fondent la science informatique.

Photo d'Alan Turing
Alan Turing
La machine de Turing

Alan Turing présente en 1936 une machine imaginaire, pure création de l'esprit, nommée depuis machine de Turing.

Une machine de Turing est une machine mécanique virtuelle, un mécanisme simple qui, s'il était réellement conçu, permettrait d'exécuter des algorithmes. Elle fut inventée avant le premier ordinateur.

La machine de Turing se compose :

  1. d'un ruban infini divisé en cases qui peuvent contenir un ensemble fini de symboles : mathématiquement, cela revient à un tableau possèdant des indices i.
  2. d'une tête de lecture-écriture qui peut se déplacer d'une case à la fois, à droite ou à gauche et lire et écrire sur la case au dessus de laquelle elle se trouve. Mathématiquement, cela revient à modifier la variable i.
  3. d'un registre d'état enregistrant un nombre fini d'états ("DEPART", "PHASE1", "PHASE2", 'FINI'...). Mathématiquement, cela revient à définir une variable qui contient le numéro de l'état.
  4. Une table d'actions. C'est un tableau à deux entrées qui indique ce qu'on doit faire lorsque la machine lit un symbole sur une case et étant dans.un état précis. Mathématiquement c'est une fonction qui reçoit le caractère lu, l'état de la tête et renvoie un caractère à écrire, le nouvel état de la tête et un le déplacement à faire.
https://fr.wikipedia.org/wiki/Machine_de_Turing#/media/Fichier:Maquina.png
Vue d'artiste de la machine de Turing (domaine public, publié sur Wikipedia)

On ne parlera pas plus de cette machine mais vous voyez qu'on peut la représenter mathématiquement. Donc, on peut démontrer de choses sur ce qu'elle peut calculer et ce qu'elle ne peut pas calculer.

Avec cette machine de l'esprit, Turing est parvenu à définir ce qui sera calculable un jour sur un ordinateur, une machine qui n'existait même pas encore.

Alan Turing est donc vu comme l'un des pères de l'informatique.

Alan Turing et l'Histoire

Ceci fut classé secret defense pendant de nombreuses années après la 2nd Guerre Mondiale : Alan Turing a joué un rôle majeur dans la cryptanalyse de la machine Enigma utilisée par l'armée allemande.

Sans la découverte d'un moyen de décrypter les communications cryptées par Enigma, la guerre aurait sans doute duré plus longtemps. Et comme les Nazis recherchaient également à produire la bombe atomique, l'enjeu de la rapidité était considérable.

Après la guerre, Alan Turing participa

  • à l'élaboration des premiers ordinateurs,
  • aux études initiales sur l'intelligence artificielle et
  • à certaines études liant informatique et biologie.

Il sera poursuivi en justice pour son homosexualité en 1952 et fut retrouvé mort, empoisonné au cyanure, chez lui en 1954. Il n'avait alors que 41 ans. Rien ne prouve qu'il s'agisse d'un suicide, d'un simple accident ou d'un meutre discret.

Le rôle fondamental d'Alan Turing lors de la guerre ne sera révélé qu'en 1970. Avant cette date, son implication dans l'effort de guerre était classifiée secret-defense.

4 - Architecture de von Neumann

John von Neumann (1903-1957) est un mathématicien et physicien américano-hongrois.

Il a apporté de nombreux travaux autant en physique quantique, en mathématiques qu'en économie.

Sa contribution à l'informatique est immense puisque tous les ordinateurs utilisent l'architecture qu'il a établi.

https://commons.wikimedia.org/wiki/File:JohnvonNeumann-LosAlamos.jpg
Cette image appartient à Los Alamos National Laboratory. La société permet l'utilisation de cette photo sous condition d'en préciser le propriétaire

Nous nous étions demandé où stocker les instructions de la machine M10. S'inspirant de la machine de Turing, la réponse de von Neumann est de placer les données et les programmes au même endroit. La puissance de von Neumann fut de parvenir à passer de l'idée de cette machine à sa concrétisation et à la rendre réellement rapide. La machine de Turing ne bouge que d'une case à la fois.

Structure d'un ordinateur (version 1er)
Memoire UDC UAL Accumulateur Accumulateur Entrée Sortie

Un ordinateur est composé :

  1. D'une mémoire centrale (RAM, mémoire vive) qui permet de stocker les données et les instructions. Il s'agit d'une mémoire volatile car elle disparait lorsqu'on coupe l'alimentation. Elle est donc vide au démarrage.
  2. D'un processeur également nommé UDT ou CPU (Unité de Traitement ou Central Processing Unit). Il est composé de
    • l'UDC (unité de contrôle) qui lit et interprète les instructions ;
    • l'UAL (unité arithmétique et logique) qui exécute ce que l'UDC lui dit de faire ;
    • de registres.
  3. Les flèches représentent ce qu'on nomme les bus : un bus de 64 bits est constitué de 64 "fils électriques" qui permettent de faire transiter 64 bits simultanément. Si on doit transporter 128 bits avec des bus de 64 bits, il faudra donc faire 2 opérations de transport.

08° Le système doit pouvoir transporter en une seule opération une adresse via le bus d'adresses.

  • Combien d'adresses-mémoires RAM différentes peut-on avoir dans un ordinateur dont le bus d'adresse est un bus 16 bits ?
  • Si on considère que chaque case mémoire correspond à un octet, quelle est la taille maximale de la RAM sur ce système

...CORRECTION...

Il faut calculer à chaque fois 216 pour avoir le nombre d'adresses différentes.

216 = 65536.

On dispose donc de 65536 adresses différentes uniquement.

Si le bus de données est un bus de 8 bits, cela veut dire qu'on ne peut stocker qu'un octet par case mémoire : on dispose donc de 65536 octets, soit un peu plus de 65 ko de mémoire vive.

09° Faire de même pour un ordinateur muni d'un processeur 32 bits, et de bus d'adresses de 32 bits.

...CORRECTION...

Il faut calculer à chaque fois 232 pour avoir le nombre d'adresses différentes.

232 = 4294967296.

On dispose donc de 4294967296 adresses différentes.

En prenant des cases de 1 octet, on aura donc au maximum un peu plus de 4 Go de mémoire vive disponible.

10° Votre disque dur correspond-t-il à une mémoire vive (RAM) ou à une mémoire de masse ?

...CORRECTION...

Le disque dur n'est pas de la RAM, il correspond à une mémoire de masse non volatile : la capacité mémoire est beaucoup plus grande que celle de la RAM mais le temps d'accès également.

C'est pour cela que lorsque vous démrarrez un logiciel, on place son code dans la RAM ainsi que les fichiers en cours d'utilisation. Sans cela, le système serait très lent.

11° Combien d'opérations pour stocker ou lire un grand entier stocké sur 4 octets avec un bus de données de 8 bits ?

...CORRECTION...

On va devoir transférer les 4 octets en quatre étapes : 8 bits à la fois !

On dit qu'il faut 4 temps-machine.

12° Combien d'opérations pour stocker ou lire un grand entier stocké sur 4 octets avec un bus de données de 32 bits connaissant l'adresse mémoire du premier octet ?

...CORRECTION...

Cette fois, on peut ramener 4 octets à la fois directement (4 octets = 32 bits). Il suffit donc d'un temps-machine.

13° Avec un système 64 bits, la lecture d'un entier sur 4 octets va-t-elle être plus rapide qu'avec un système 32 bits ?

...CORRECTION...

Non : cette fois, nous n'allons en réalité utiliser que 32 bits sur les 64 bits. On ne gagne donc pas de temps par rapport à un bus de 32 bus.

14° Dans quel cas le système 64 bits va-t-il être plus efficace ?

...CORRECTION...

Lorsqu'on aura besoin de ramener des données stockées sur 5 octets ou plus : lorsqu'on doit faire de vraiment gros calculs. Pour certains jeux vidéos 3D avec des textures très réalistes par exemple....

5 - L'année prochaine : M999

Reste que pour l'instant, nous avons dit que le programme et les données étaient dans la même mémoire mais nous ne l'avons pas montré.

Vous le verrez en Terminale avec la machine M999.

Structure de M99
Sur la base de ressources cc-by-sa Philippe Marquet, Martin Quinson «M999, le processeur débranché» : github.com/InfoSansOrdi/M999

Retenons donc :

Qu'on peut concevoir des ordinateurs comportant :

  • Une mémoire centrale contenant à la fois les données et les programmes. Le tout sous forme d'octets.
  • D'un processeur (CPU) composé principalement d'une unité de commande (UDC, gérant les instructions lues en mémoire), d'une unité arithmétique et logique (UAL), de plusieurs registres
  • et les bus permettant de faire communiquer tout cela.

Ceci est la structure générale. Il reste bien entendu beaucoup d'autres mécanismes non abordés permettant à l'ensemble de fonctionner : l'horloge par exemple. C'est cette puce qui envoie régulièrement une impulsion pour synchroniser les différentes parties entre elles de façon à ce qu'elles puissent se coordonner.

6 - FAQ

Rien pour le moment

Voilà pour l'introduction. Vous venez donc de voir ce qu'est l'assembleur. Et pourquoi l'Amiral Grace Hopper a mis tant d'énergie dans la création du premier langage haut niveau !

Dans la prochaine activité, nous verrons d'abord comment les ordinateurs parviennent à réaliser des opérations basiques comme l'addition ou comme l'utilisation de ET ou du OU.

Activité publiée le 09 02 2020
Dernière modification : 14 02 2021
Auteur : ows. h.