Aller au contenu

Partie 2 : Langage machine et assembleur


Un programme passe par plusieurs niveaux entre ce que le programmeur écrit et ce que le processeur exécute :

Langage de haut niveau (Python, JavaScript...)
│
▼ (compilation ou interprétation)
Langage assembleur (mnémoniques : ADD, MOV, CMP...)
│
▼ (assemblage)
Langage machine (suite de 0 et de 1)
│
▼ (exécution)
Processeur (circuits électroniques)
NiveauExempleLisibilité
Langage de haut niveaux = x + 1Facile
AssembleurADD R0, R0, #1Moyen
Langage machine11100010100000000000000000000001Illisible

Le langage machine est le seul langage compris directement par le processeur. Chaque instruction est codée en binaire et comprend deux parties :

  • Le code opération (opcode) : indique l'opération à effectuer (addition, transfert, saut...)
  • Les opérandes : indiquent les données sur lesquelles opérer (registre, adresse mémoire, valeur immédiate)
┌──────────────┬───────────────────────┐
│ Code opér. │ Opérandes │
│ (opcode) │ (registres, adresses) │
└──────────────┴───────────────────────┘

Programmer en langage machine est extrêmement difficile (longues suites de 0 et de 1), c'est pourquoi on utilise l'assembleur.


L'assembleur remplace les codes binaires par des mnémoniques (abréviations faciles à retenir). Un programme appelé « assembleur » traduit ces mnémoniques en langage machine.

Par exemple : ADD R1, R0, #128 est bien plus lisible que 11100010100000000000000010000000.

Les instructions assembleur se répartissent en trois catégories :

InstructionSignificationExemple
LDR Rd, adrCharger en registre depuis la mémoireLDR R1, 78 → R1 ← mémoire[78]
STR Rd, adrStocker un registre en mémoireSTR R3, 125 → mémoire[125] ← R3
MOV Rd, #valPlacer une valeur immédiate dans un registreMOV R1, #23 → R1 ← 23
MOV Rd, RsCopier un registre dans un autreMOV R0, R3 → R0 ← R3
InstructionSignificationExemple
ADD Rd, Rs, #valAddition avec une valeur immédiateADD R1, R0, #128 → R1 ← R0 + 128
ADD Rd, Rs, RtAddition de deux registresADD R0, R1, R2 → R0 ← R1 + R2
SUB Rd, Rs, #valSoustraction avec une valeur immédiateSUB R1, R0, #128 → R1 ← R0 - 128
SUB Rd, Rs, RtSoustraction de deux registresSUB R0, R1, R2 → R0 ← R1 - R2
InstructionSignification
CMP Ra, #valCompare Ra avec une valeur (prépare un branchement)
CMP Ra, RbCompare Ra avec Rb
B adrBranchement inconditionnel (saut à l'adresse)
BEQ adrBranchement si égal (Branch if Equal)
BNE adrBranchement si différent (Branch if Not Equal)
BGT adrBranchement si supérieur (Branch if Greater Than)
BLT adrBranchement si inférieur (Branch if Less Than)
HALTArrêt du programme

Un opérande peut être de trois natures :

TypeNotationExemple
Valeur immédiate#valeurMOV R0, #42 (R0 ← 42)
RegistreRnADD R0, R1, R2 (R0 ← R1 + R2)
Adresse mémoireadresseLDR R1, 78 (R1 ← mémoire[78])

Calculer 5 + 3 et stocker le résultat en mémoire à l'adresse 100 :

MOV R0, #5 ← R0 = 5
MOV R1, #3 ← R1 = 3
ADD R2, R0, R1 ← R2 = R0 + R1 = 8
STR R2, 100 ← mémoire[100] = 8
HALT ← fin du programme

Déroulement pas à pas :

ÉtapeInstructionR0R1R2mémoire[100]
1MOV R0, #55---
2MOV R1, #353--
3ADD R2, R0, R1538-
4STR R2, 1005388
5HALT----

Programme Python :

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

Programme assembleur équivalent (x en mémoire 30, y en mémoire 75, z en mémoire 23) :

MOV R0, #4 ← x = 4
STR R0, 30 ← mémoire[30] = x
MOV R0, #8 ← y = 8
STR R0, 75 ← mémoire[75] = y
LDR R0, 30 ← R0 = x
CMP R0, #10 ← comparer x à 10
BNE sinon ← si x ≠ 10, aller à sinon
MOV R0, #9 ← y = 9
STR R0, 75
B fin ← sauter le bloc sinon
sinon:
LDR R0, 30 ← R0 = x
ADD R0, R0, #1 ← x = x + 1
STR R0, 30
fin:
MOV R0, #6 ← z = 6
STR R0, 23
HALT

Comme x = 4 ≠ 10, le branchement BNE sinon est pris : on exécute x = x + 1, ce qui donne x = 5. Puis z = 6.

Programme Python :

s = 0
for i in range(1, 4):
s = s + i

Programme assembleur (s en mémoire 50, i en mémoire 51) :

MOV R0, #0 ← s = 0
STR R0, 50
MOV R1, #1 ← i = 1
STR R1, 51
boucle:
CMP R1, #4 ← comparer i à 4
BEQ fin ← si i == 4, sortir de la boucle
LDR R0, 50 ← R0 = s
ADD R0, R0, R1 ← s = s + i
STR R0, 50
ADD R1, R1, #1 ← i = i + 1
STR R1, 51
B boucle ← retour au début de la boucle
fin:
HALT

Déroulement :

Itérationis avants + is après
1100 + 11
2211 + 23
3333 + 36

Résultat final : s = 6.


Pour expérimenter avec l'assembleur, on peut utiliser le simulateur de Peter L. Higginson qui permet de programmer en assembleur et de visualiser l'état des registres et de la mémoire à chaque étape.

L'interface montre :

  • Les registres (R0 à R12, IP, etc.) et leur contenu
  • La mémoire RAM avec les instructions et les données
  • Le déroulement pas à pas de l'exécution

  • Le processeur ne comprend que le langage machine (suites de 0 et 1).
  • L'assembleur utilise des mnémoniques lisibles (ADD, MOV, CMP...) traduites en langage machine.
  • Trois types d'instructions : transfert (LDR, STR, MOV), arithmétique (ADD, SUB), contrôle (CMP, B, BEQ, BNE, BGT, BLT).
  • Le # indique une valeur immédiate, les noms R0, R1... désignent des registres, un nombre seul est une adresse mémoire.
  • Le cycle d'exécution : chargement (lire en mémoire) → décodage (analyser) → exécution (effectuer).
  • Les structures de contrôle (if, for) se traduisent en assembleur par des comparaisons (CMP) suivies de branchements conditionnels (BEQ, BNE...).