← Retour au blog

Image principale

#assembleur #programmation #langage-bas-niveau #cpu #machine-code

Si t’aimes comprendre comment les choses marchent vraiment sous le capot, l’assembleur est un passage obligé. C’est littéralement la langue maternelle de ton processeur — celle qu’il parle sans traducteur.

Aujourd’hui, la plupart des devs codent en Python, C ou Rust, mais au final, tout finit traduit en instructions assembleur avant de devenir des 0 et des 1. Autant dire que toucher à ce langage, c’est remonter à la source.

---

⚙️ Qu’est-ce que l’assembleur ?

L’assembleur, c’est un langage symbolique qui fait le pont entre l’humain et la machine. Chaque ligne correspond à une instruction CPU. Pas de framework, pas de sucre syntaxique — juste du pur contrôle.

Voici un petit exemple x86 :

; Addition simple en assembleur x86
MOV AX, 5      ; Charger la valeur 5 dans le registre AX
MOV BX, 3      ; Charger la valeur 3 dans le registre BX
ADD AX, BX     ; AX = AX + BX → AX = 8
INT 20h        ; Interruption système : fin du programme

Ici, on manipule directement les registres. Pas d’interpréteur, pas de runtime — toi et la machine, face à face.

Schéma d’architecture CPU et registres
Schéma d’architecture CPU et registres

---

🧠 Registres et mémoire

Les registres, c’est le terrain de jeu du CPU. Ce sont de petites zones de stockage ultra-rapides qui servent à faire des calculs ou manipuler des adresses mémoire. Et selon le processeur, les noms changent :

| Architecture | Exemples de registres | | --- | --- | | x86 (Intel) | AX, BX, CX, DX, SI, DI, SP, BP | | ARM | R0, R1, R2, R3, SP, LR, PC | | RISC-V | x0–x31, SP, RA |

Exemple :

MOV AX, [2000h] ; Charger dans AX la valeur à l’adresse mémoire 0x2000
ADD AX, 1       ; Incrémenter cette valeur
MOV [2000h], AX ; Sauvegarder le résultat

Là, on touche à la mémoire vive en direct. Pas de malloc(), pas de pointeur magique — juste des adresses hexadécimales et des instructions brutes.

---

🔍 Assembleur et langage machine

Chaque ligne d’assembleur est en fait une représentation lisible d’un code binaire que le CPU comprend. Par exemple :

MOV AX, 1
ADD AX, 2

Correspond à ces instructions machine :

B8 01 00
83 C0 02

Et c’est ça que le processeur exécute — des octets, rien d’autre. C’est fascinant de se dire que tout ton OS, ton navigateur ou même ton jeu vidéo préféré ne sont, au fond, qu’une immense suite d’instructions de ce type.

---

🧩 Exemple complet (NASM sous Linux x86-64)

Un exemple concret pour les curieux : voici un petit programme qui affiche un message dans le terminal.

section .data
msg db 'Hello, Assembleur!', 0xA  ; Message + saut de ligne
len equ $ - msg                   ; Longueur du message

section .text
global _start

_start:
  mov rax, 1        ; Appel système: write
  mov rdi, 1        ; Sortie standard (stdout)
  mov rsi, msg      ; Adresse du message
  mov rdx, len      ; Taille du message
  syscall           ; Appel du noyau Linux

  mov rax, 60       ; Appel système: exit
  xor rdi, rdi      ; Code de retour 0
  syscall

Compilation et exécution :

nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello

Résultat :

Hello, Assembleur!

Cycle d’exécution NASM et traduction binaire
Cycle d’exécution NASM et traduction binaire

---

🚀 Conclusion

L’assembleur, c’est un peu comme la forge du code : brut, précis, sans triche. Il ne ment pas, il ne cache rien. Quand tu comprends comment une instruction circule du registre au bus, tu ne vois plus jamais un programme de la même façon.

Apprendre un peu d’assembleur, c’est pas pour tout coder avec, c’est pour comprendre ce qu’on fait vraiment quand on code. Et ça, c’est une claque intellectuelle que tout développeur devrait vivre au moins une fois.

Penser comme la machine, c’est apprendre à coder sans illusion.