Numérique et Sciences Informatiques > Histoire de l'Informatique > L'Évolution des Langages de Programmation > Langages machine et assembleur

Exemple concret : Additionner deux nombres en Assembleur

Cet exemple illustre comment additionner deux nombres en langage assembleur, fournissant une compréhension pratique de la programmation de bas niveau.

Architecture et Registres

Avant de commencer, il est essentiel de comprendre les concepts de base de l'architecture du processeur, notamment les registres. Les registres sont de petites zones de stockage de données à l'intérieur du processeur, accessibles très rapidement. Pour cet exemple, nous utiliserons une architecture simplifiée de type x86.

  • Registres généraux: `AX`, `BX`, `CX`, `DX` sont des registres généraux utilisés pour stocker des données et effectuer des opérations.
  • Registres pointeurs: `SP` (Stack Pointer) pointe vers le sommet de la pile, `BP` (Base Pointer) est utilisé pour accéder aux données dans la pile.
  • Registre d'instruction: `IP` (Instruction Pointer) pointe vers l'instruction suivante à exécuter.
Nous utiliserons les registres `AX` et `BX` pour stocker les nombres à additionner, et le résultat sera stocké dans `AX`.

Le Code Assembleur

Voici un exemple de code assembleur pour additionner deux nombres : ; Programme pour additionner deux nombres section .data nombre1 dw 5 ; Définir nombre1 comme un mot (word) de 16 bits avec la valeur 5 nombre2 dw 10 ; Définir nombre2 comme un mot (word) de 16 bits avec la valeur 10 section .text global _start ; Point d'entrée du programme _start: ; Charger nombre1 dans le registre AX mov ax, [nombre1] ; Déplacer le contenu de l'adresse mémoire de nombre1 dans AX ; Charger nombre2 dans le registre BX mov bx, [nombre2] ; Déplacer le contenu de l'adresse mémoire de nombre2 dans BX ; Additionner AX et BX, le résultat est stocké dans AX add ax, bx ; Ajouter le contenu de BX à AX ; AX contient maintenant le résultat (5 + 10 = 15) ; Sortir du programme (code de sortie 0) mov eax, 1 ; Numéro de l'appel système pour exit xor ebx, ebx ; Code de sortie 0 int 0x80 ; Interruption pour appeler le système d'exploitation Explication du code:

  • `section .data`: Définit la section des données où sont stockées les variables `nombre1` et `nombre2`. `dw` signifie "define word", indiquant que les variables sont des mots de 16 bits.
  • `section .text`: Définit la section du code où sont stockées les instructions.
  • `global _start`: Définit le point d'entrée du programme.
  • `mov ax, [nombre1]`: Déplace le contenu de l'adresse mémoire de `nombre1` dans le registre `AX`. Les crochets `[]` indiquent que l'on accède au contenu de l'adresse mémoire.
  • `mov bx, [nombre2]`: Déplace le contenu de l'adresse mémoire de `nombre2` dans le registre `BX`.
  • `add ax, bx`: Additionne le contenu de `AX` et `BX`, et stocke le résultat dans `AX`.
  • `mov eax, 1`: Prépare l'appel système pour quitter le programme. `eax` est utilisé pour spécifier le numéro de l'appel système (1 pour `exit`).
  • `xor ebx, ebx`: Met la valeur de `ebx` à zéro (code de sortie).
  • `int 0x80`: Déclenche l'interruption 0x80, qui appelle le système d'exploitation pour exécuter l'appel système spécifié dans `eax`.

Assemblage et Exécution

Pour assembler et exécuter ce code, vous aurez besoin d'un assembleur (comme NASM ou MASM) et d'un linker. Étapes:

  1. Écrire le code: Écrivez le code assembleur dans un fichier (par exemple, `addition.asm`).
  2. Assembler le code: Utilisez un assembleur pour traduire le code assembleur en code objet. Par exemple, avec NASM : nasm -f elf32 addition.asm (pour un système 32 bits).
  3. Linker le code: Utilisez un linker pour combiner le code objet avec les bibliothèques nécessaires et créer un exécutable. Par exemple, avec ld : ld -m elf_i386 addition.o -o addition.
  4. Exécuter le programme: Exécutez le programme : ./addition.
Bien que ce programme ne produise pas de sortie visible, le résultat de l'addition (15) sera stocké dans le registre `AX` après l'exécution de l'instruction `add ax, bx`. Vous pouvez utiliser un débogueur pour examiner le contenu des registres.

Ce qu'il faut retenir

  • Les registres (AX, BX, etc.) sont des zones de stockage rapides dans le processeur.
  • L'instruction `mov` permet de déplacer des données entre la mémoire et les registres.
  • L'instruction `add` permet d'additionner des valeurs stockées dans les registres.
  • L'assembleur traduit le code assembleur en code machine exécutable.
  • Le linker combine le code objet avec les bibliothèques nécessaires pour créer un exécutable.

FAQ

  • Pourquoi utiliser des adresses mémoire entre crochets `[]` dans `mov ax, [nombre1]`?

    Les crochets `[]` indiquent que l'on accède au contenu de l'adresse mémoire spécifiée par `nombre1`. Sans les crochets, `mov ax, nombre1` déplacerait l'adresse mémoire elle-même dans `AX`, et non la valeur stockée à cette adresse.
  • Quel est le rôle de l'appel système `int 0x80`?

    L'appel système `int 0x80` est une instruction qui interrompt l'exécution du programme et appelle le système d'exploitation pour effectuer une tâche spécifique (ici, quitter le programme). Le numéro de l'appel système est spécifié dans le registre `eax`.