Apprendre à programmer

Exercices corrigés sur la programmation en assembleur (Assembly)

Voici une série d’exercices corrigés sur la programmation en assembleur (Assembly), une des plus anciennes et des plus proches du matériel des langages de programmation. Ces exercices couvriront des aspects de base comme les opérations arithmétiques, les branchements conditionnels, la gestion de boucles, et la manipulation de registres. Les exemples utiliseront une architecture courante telle que x86.


Exercice 1 : Addition de deux nombres

Contexte :

Écrire un programme en assembleur qui additionne deux nombres, les charge dans les registres AX et BX, puis place le résultat dans CX.

Correction (x86) :

section .data
    num1 dw 5        ; Premier nombre
    num2 dw 7        ; Deuxième nombre

section .text
    global _start

_start:
    mov ax, [num1]    ; Charger num1 dans AX
    mov bx, [num2]    ; Charger num2 dans BX
    add ax, bx        ; Ajouter AX et BX
    mov cx, ax        ; Placer le résultat dans CX

    ; Sortie du programme (pour un système Unix)
    mov eax, 60       ; Code système pour exit
    xor edi, edi      ; Retourner 0
    syscall

Explication :

  • mov ax, [num1] : Charge la valeur de num1 dans le registre AX.
  • mov bx, [num2] : Charge la valeur de num2 dans le registre BX.
  • add ax, bx : Additionne les valeurs dans AX et BX, le résultat est stocké dans AX.
  • mov cx, ax : Le résultat est copié dans CX.

Exercice 2 : Multiplication de deux nombres

Contexte :

Écrire un programme en assembleur qui multiplie deux nombres. Les valeurs sont chargées dans les registres AX et BX, et le résultat est stocké dans DX:AX.

Correction (x86) :

section .data
    num1 dw 8        ; Premier nombre
    num2 dw 3        ; Deuxième nombre

section .text
    global _start

_start:
    mov ax, [num1]    ; Charger num1 dans AX
    mov bx, [num2]    ; Charger num2 dans BX
    imul bx           ; Multiplie AX par BX, résultat dans DX:AX

    ; Sortie du programme
    mov eax, 60       ; Code système pour exit
    xor edi, edi      ; Retourner 0
    syscall

Explication :

  • mov ax, [num1] : Charge la valeur de num1 dans AX.
  • mov bx, [num2] : Charge la valeur de num2 dans BX.
  • imul bx : Multiplie AX par BX, le résultat est stocké dans DX:AX (car l’opération peut générer un résultat de 32 bits, réparti sur deux registres).

Exercice 3 : Boucle avec addition répétée

Contexte :

Écrire un programme en assembleur qui additionne les nombres de 1 à 5 en utilisant une boucle, et place le résultat final dans AX.

Correction (x86) :

section .data
    sum dw 0          ; Variable pour stocker la somme
    counter dw 1      ; Compteur initialisé à 1

section .text
    global _start

_start:
    mov cx, 5         ; Répéter 5 fois
    mov ax, 0         ; Initialiser la somme dans AX

loop_start:
    add ax, [counter] ; Ajouter la valeur du compteur à AX
    inc word [counter]; Incrémenter le compteur
    loop loop_start   ; Décrémenter CX et répéter la boucle si CX > 0

    ; Sortie du programme
    mov eax, 60       ; Code système pour exit
    xor edi, edi      ; Retourner 0
    syscall

Explication :

  • mov cx, 5 : Initialise le registre CX à 5 pour exécuter la boucle 5 fois.
  • add ax, [counter] : Ajoute la valeur du compteur à AX.
  • inc word [counter] : Incrémente la valeur du compteur après chaque addition.
  • loop loop_start : Décrémente CX et continue tant que CX n’atteint pas 0.

Exercice 4 : Comparaison de deux nombres

Contexte :

Écrire un programme en assembleur qui compare deux nombres et détermine si le premier est supérieur, inférieur ou égal au second. Affichez le résultat en utilisant des étiquettes conditionnelles.

Correction (x86) :

section .data
    num1 dw 6        ; Premier nombre
    num2 dw 6        ; Deuxième nombre

section .text
    global _start

_start:
    mov ax, [num1]    ; Charger num1 dans AX
    mov bx, [num2]    ; Charger num2 dans BX
    cmp ax, bx        ; Comparer AX et BX

    je equal          ; Si égal, sauter à "equal"
    jg greater        ; Si supérieur, sauter à "greater"
    jl less           ; Si inférieur, sauter à "less"

equal:
    ; Les nombres sont égaux
    mov eax, 1        ; Simule une sortie avec code 1
    jmp end_program

greater:
    ; num1 est supérieur à num2
    mov eax, 2        ; Simule une sortie avec code 2
    jmp end_program

less:
    ; num1 est inférieur à num2
    mov eax, 3        ; Simule une sortie avec code 3

end_program:
    xor edi, edi      ; Retourner 0
    syscall

Explication :

  • cmp ax, bx : Compare AX à BX.
  • je equal : Si les deux nombres sont égaux, saute à l’étiquette equal.
  • jg greater : Si AX est plus grand que BX, saute à greater.
  • jl less : Si AX est plus petit que BX, saute à less.

Exercice 5 : Utilisation d’une fonction en assembleur

Contexte :

Écrire un programme en assembleur qui appelle une fonction pour additionner deux nombres. Le programme principal charge les valeurs, et la fonction additionne les nombres avant de retourner le résultat.

Correction (x86) :

section .data
    num1 dw 12
    num2 dw 8

section .text
    global _start

_start:
    mov ax, [num1]    ; Charger num1 dans AX
    mov bx, [num2]    ; Charger num2 dans BX

    call add_numbers  ; Appel de la fonction

    ; Sortie du programme
    mov eax, 60       ; Code système pour exit
    xor edi, edi      ; Retourner 0
    syscall

add_numbers:
    add ax, bx        ; Additionner AX et BX
    ret               ; Retourner à l’appelant avec le résultat dans AX

Explication :

  • call add_numbers : Appelle la fonction add_numbers pour additionner AX et BX.
  • ret : Retourne le contrôle au programme principal avec le résultat dans AX.

Exercice 6 : Programme pour inverser un tableau

Contexte :

Écrire un programme en assembleur qui inverse un tableau de 5 éléments en place.

Voici la suite et fin de l’Exercice 6 sur l’inversion d’un tableau en assembleur :


Correction (suite) :

  • Les valeurs à l’indice de gauche et de droite sont échangées en utilisant les registres AX et BX.
  • add esi, 2 et sub edi, 2 : Ces instructions modifient les pointeurs pour les rapprocher l’un de l’autre (car chaque élément du tableau est de 2 octets).
  • cmp esi, edi : Vérifie si les pointeurs se sont croisés ou si l’algorithme a atteint le milieu du tableau.

Exercice 7 : Factorielle d’un nombre

Contexte :

Écrire un programme en assembleur qui calcule la factorielle d’un nombre stocké en mémoire. Le résultat sera retourné dans AX.

Correction (x86) :

section .data
    num dw 5            ; Nombre dont on veut calculer la factorielle
    result dw 1         ; Résultat (initialisé à 1)

section .text
    global _start

_start:
    mov ax, [num]        ; Charger le nombre dans AX
    mov bx, ax           ; Sauvegarder le nombre dans BX
    mov cx, ax           ; Utiliser CX comme compteur

    ; Boucle pour calculer la factorielle
factorial_loop:
    cmp cx, 1            ; Si CX est égal à 1, fin de la boucle
    jle end_factorial    ; Sauter si CX <= 1

    imul bx, cx          ; Multiplier BX (résultat partiel) par CX
    loop factorial_loop  ; Décrémenter CX et répéter

end_factorial:
    mov [result], bx     ; Sauvegarder le résultat final dans la mémoire

    ; Sortie du programme
    mov eax, 60          ; Code système pour exit
    xor edi, edi         ; Retourner 0
    syscall

Explication :

  • mov ax, [num] : Charge le nombre dont on veut calculer la factorielle.
  • cmp cx, 1 : Compare le compteur CX avec 1 ; si CX est égal ou inférieur à 1, la boucle s’arrête.
  • imul bx, cx : Multiplie le registre BX (qui contient le résultat partiel) par CX à chaque itération.
  • loop factorial_loop : Décrémente CX et répète la boucle jusqu’à atteindre 1.

Exercice 8 : Programme avec interruption pour affichage de texte

Contexte :

Écrire un programme en assembleur qui utilise une interruption système pour afficher une chaîne de caractères à l’écran.

Correction (x86, pour DOS) :

section .data
    message db 'Bonjour Assembleur!', 0xA, 0xD, '$'  ; Message avec nouvelle ligne et fin de chaîne

section .text
    global _start

_start:
    mov ah, 0x09            ; Fonction d'affichage de chaîne (DOS)
    mov dx, message         ; Charger l'adresse du message dans DX
    int 0x21                ; Appel de l'interruption pour afficher le texte

    ; Sortie du programme
    mov ax, 0x4C00          ; Terminer le programme (DOS)
    int 0x21                ; Appel de l'interruption pour quitter

Explication :

  • mov ah, 0x09 : Charge la fonction d’affichage de texte dans AH (interruption DOS).
  • int 0x21 : Utilise l’interruption 0x21 pour afficher la chaîne terminée par le caractère ‘$’.
  • Le programme affiche « Bonjour Assembleur! » suivi d’un retour à la ligne.

Exercice 9 : Réalisation d’une somme de tableaux

Contexte :

Écrire un programme en assembleur qui additionne deux tableaux de 5 éléments et stocke le résultat dans un troisième tableau.

Correction (x86) :

section .data
    array1 dw 1, 2, 3, 4, 5      ; Premier tableau
    array2 dw 5, 4, 3, 2, 1      ; Deuxième tableau
    result dw 5 dup(0)           ; Tableau pour stocker le résultat (initialisé à 0)
    n dw 5                       ; Taille des tableaux

section .text
    global _start

_start:
    mov esi, array1              ; Pointeur sur array1
    mov edi, array2              ; Pointeur sur array2
    mov edx, result              ; Pointeur sur result
    mov cx, [n]                  ; Nombre d'éléments dans les tableaux

sum_loop:
    mov ax, [esi]                ; Charger l'élément de array1
    add ax, [edi]                ; Ajouter l'élément correspondant de array2
    mov [edx], ax                ; Stocker le résultat dans result

    ; Incrémenter les pointeurs
    add esi, 2
    add edi, 2
    add edx, 2

    loop sum_loop                ; Décrémenter CX et répéter la boucle

    ; Sortie du programme
    mov eax, 60                  ; Code système pour exit
    xor edi, edi                 ; Retourner 0
    syscall

Explication :

  • mov esi, array1 et mov edi, array2 : Pointeurs pour parcourir les deux tableaux.
  • add ax, [edi] : Additionne les éléments correspondants de array1 et array2.
  • mov [edx], ax : Stocke le résultat dans le tableau result.
  • loop sum_loop : Continue jusqu’à ce que tous les éléments soient additionnés.

Exercice 10 : Programme d’incrémentation de compteur avec saut conditionnel

Contexte :

Écrire un programme en assembleur qui incrémente un compteur jusqu’à une valeur donnée et arrête lorsque la valeur 10 est atteinte.

Correction (x86) :

section .data
    counter dw 0         ; Compteur initialisé à 0
    limit dw 10          ; Limite fixée à 10

section .text
    global _start

_start:
    mov cx, [counter]    ; Charger la valeur du compteur
    mov ax, [limit]      ; Charger la limite

increment_loop:
    inc cx               ; Incrémenter le compteur
    cmp cx, ax           ; Comparer le compteur à la limite
    je end_loop          ; Si le compteur atteint la limite, sauter à end_loop

    jmp increment_loop   ; Répéter la boucle

end_loop:
    ; Sortie du programme
    mov eax, 60          ; Code système pour exit
    xor edi, edi         ; Retourner 0
    syscall

Explication :

  • inc cx : Incrémente le compteur à chaque itération.
  • cmp cx, ax : Compare le compteur avec la limite.
  • je end_loop : Si la valeur du compteur atteint 10, le programme se termine.

Ces exercices couvrent les bases de la programmation assembleur, en passant par les opérations arithmétiques, la gestion de boucles, les comparaisons et l’utilisation d’interruptions. Ils vous aident à comprendre comment interagir avec les registres, gérer la mémoire et exécuter des opérations conditionnelles dans le contexte d’un processeur.

Voici une série d’exercices en assembleur couvrant des cas particuliers qui sont moins courants ou plus complexes, touchant des aspects spécifiques comme la gestion de débordements, l’optimisation mémoire, la gestion de nombres signés, ou encore des manipulations plus avancées de registres et d’interruptions.


Exercice 1 : Gestion du débordement lors d’une addition

Contexte :

Écrire un programme en assembleur qui effectue l’addition de deux grands nombres. Si un débordement se produit (c’est-à-dire que le résultat dépasse la capacité des registres), le programme devra signaler l’erreur.

Correction (x86) :

section .data
    num1 dw 40000        ; Premier nombre (grand pour provoquer un débordement)
    num2 dw 30000        ; Deuxième nombre

section .text
    global _start

_start:
    mov ax, [num1]       ; Charger num1 dans AX
    add ax, [num2]       ; Ajouter num2 à AX

    jo overflow_error    ; Si un débordement se produit, sauter à "overflow_error"

    ; Si pas de débordement, continuer normalement
    jmp end_program      ; Sauter à la fin du programme

overflow_error:
    ; Gestion de l'erreur de débordement (simuler un code d'erreur, par exemple)
    mov eax, 1           ; Code d'erreur

end_program:
    ; Sortie du programme
    mov eax, 60          ; Code système pour exit
    xor edi, edi         ; Retourner 0
    syscall

Explication :

  • jo overflow_error : Instruction qui détecte un débordement lors d’une opération d’addition (flag OF activé). Si c’est le cas, elle saute à l’étiquette overflow_error.
  • Si aucun débordement ne se produit, le programme continue normalement.

Exercice 2 : Multiplication et gestion du signe

Contexte :

Écrire un programme en assembleur qui multiplie deux nombres signés (positifs ou négatifs) et place le résultat dans un registre. Le programme doit également gérer le signe du résultat correctement.

Correction (x86) :

section .data
    num1 dw -7          ; Premier nombre signé (négatif)
    num2 dw 5           ; Deuxième nombre signé (positif)

section .text
    global _start

_start:
    mov ax, [num1]      ; Charger num1 dans AX
    imul word [num2]    ; Multiplier num1 par num2 (signé)

    ; Le résultat est dans DX:AX, mais ici, DX ne sera pas utilisé pour des petits nombres

    ; Sortie du programme
    mov eax, 60         ; Code système pour exit
    xor edi, edi        ; Retourner 0
    syscall

Explication :

  • imul word [num2] : Instruction utilisée pour multiplier des entiers signés. Elle prend en compte les signes des nombres et calcule correctement le résultat en fonction du signe des opérandes.

Exercice 3 : Programme avec boucle et calcul de la somme des carrés

Contexte :

Écrire un programme en assembleur qui calcule la somme des carrés des entiers de 1 à N, où N est une valeur stockée en mémoire. Le résultat final doit être placé dans un registre.

Correction (x86) :

section .data
    N dw 5            ; Calculer la somme des carrés de 1 à N (ici N = 5)
    sum dw 0          ; Stocker la somme

section .text
    global _start

_start:
    mov cx, [N]       ; Charger N dans CX (compteur de boucle)
    mov ax, 0         ; Initialiser AX à 0 (stockage temporaire de la somme)

sum_loop:
    mov bx, cx        ; Charger la valeur actuelle de CX
    imul bx, bx       ; Calculer le carré (BX = CX * CX)
    add ax, bx        ; Ajouter le carré à la somme (AX = AX + BX)

    loop sum_loop     ; Décrémenter CX et répéter jusqu'à CX = 0

    ; Placer la somme dans [sum]
    mov [sum], ax     ; Stocker le résultat dans sum

    ; Sortie du programme
    mov eax, 60       ; Code système pour exit
    xor edi, edi      ; Retourner 0
    syscall

Explication :

  • imul bx, bx : Multiplie la valeur actuelle de CX par elle-même pour obtenir le carré.
  • loop sum_loop : Répète la boucle jusqu’à ce que CX atteigne 0. À chaque itération, la somme des carrés est calculée et ajoutée à AX.

Exercice 4 : Réduction d’une chaîne de caractères en chiffres hexadécimaux

Contexte :

Écrire un programme en assembleur qui prend une chaîne de caractères représentant des chiffres hexadécimaux (ex: « 1A3F ») et la convertit en un nombre binaire. Le résultat sera stocké dans un registre.

Correction (x86) :

section .data
    hex_string db '1A3F', 0  ; Chaîne représentant un nombre hexadécimal
    result dw 0              ; Résultat

section .text
    global _start

_start:
    mov esi, hex_string       ; Pointeur sur la chaîne
    mov ax, 0                 ; Initialiser AX pour stocker le résultat

convert_loop:
    mov al, [esi]             ; Charger le caractère suivant dans AL
    test al, al               ; Vérifier si fin de chaîne (0)
    jz end_conversion         ; Si 0, la conversion est terminée

    ; Convertir le caractère hexadécimal en sa valeur numérique
    sub al, '0'               ; Convertir les chiffres '0' à '9'
    cmp al, 9
    jle valid_digit           ; Si <= 9, c'est un chiffre valide

    sub al, 7                 ; Convertir les lettres 'A' à 'F'

valid_digit:
    shl ax, 4                 ; Décaler le résultat actuel à gauche de 4 bits (multiplication par 16)
    or ax, al                 ; Ajouter la nouvelle valeur hexadécimale

    inc esi                   ; Passer au caractère suivant
    jmp convert_loop          ; Répéter pour le caractère suivant

end_conversion:
    ; Placer le résultat final dans [result]
    mov [result], ax

    ; Sortie du programme
    mov eax, 60               ; Code système pour exit
    xor edi, edi              ; Retourner 0
    syscall

Explication :

  • shl ax, 4 : Décale le contenu d’AX vers la gauche de 4 bits pour préparer l’ajout de la nouvelle valeur hexadécimale.
  • sub al, ‘0’ : Convertit un caractère de la chaîne en une valeur numérique.
  • sub al, 7 : Pour les lettres ‘A’ à ‘F’, cette opération ajuste leur valeur dans la plage 10-15.

Exercice 5 : Inversion des bits d’un nombre

Contexte :

Écrire un programme en assembleur qui prend un entier et inverse tous ses bits. Par exemple, si l’entrée est 0b1010 (10 en décimal), le programme doit produire 0b0101.

Correction (x86) :

section .data
    number dw 0xA      ; Nombre à inverser (0b1010)

section .text
    global _start

_start:
    mov ax, [number]   ; Charger le nombre dans AX
    not ax             ; Inverser tous les bits de AX

    ; Le résultat est maintenant dans AX

    ; Sortie du programme
    mov eax, 60        ; Code système pour exit
    xor edi, edi       ; Retourner 0
    syscall

Explication :

  • not ax : Inverse tous les bits de AX, c’est-à-dire que chaque 0 devient 1 et chaque 1 devient 0.

Voici la suite et fin de l’Exercice 6 pour la génération de la séquence de Fibonacci en assembleur :


Exercice 6 : Génération d’une séquence de Fibonacci (suite)

Correction (suite) :

    mov ax, 1                 ; Deuxième terme (fibo[1] = 1)
    mov [esi], ax             ; Stocker dans fibo[1]
    add esi, 2                ; Avancer dans le tableau

    dec cx                    ; Décrémenter CX car nous avons déjà stocké deux termes
    dec cx

fib_loop:
    mov ax, [esi-2]           ; Charger le terme précédent (fibo[n-1])
    mov bx, [esi-4]           ; Charger le terme avant-dernier (fibo[n-2])
    add ax, bx                ; Calculer fibo[n] = fibo[n-1] + fibo[n-2]
    mov [esi], ax             ; Stocker le nouveau terme dans le tableau

    add esi, 2                ; Avancer dans le tableau pour le prochain terme
    loop fib_loop             ; Répéter jusqu'à CX = 0 (tous les termes générés)

    ; Sortie du programme
    mov eax, 60               ; Code système pour exit
    xor edi, edi              ; Retourner 0
    syscall

Explication :

  • mov ax, [esi-2] : Charge le terme précédent dans le registre AX.
  • mov bx, [esi-4] : Charge le terme avant-dernier dans le registre BX.
  • add ax, bx : Ajoute les deux termes précédents pour obtenir le terme suivant dans la séquence.
  • loop fib_loop : Répète la boucle jusqu’à ce que tous les termes aient été générés (CX atteint 0).

Exercice 7 : Recherche du maximum dans un tableau

Contexte :

Écrire un programme en assembleur qui parcourt un tableau d’entiers et trouve le maximum. Le résultat doit être stocké dans un registre.

Correction (x86) :

section .data
    array dw 5, 12, 7, 25, 9   ; Tableau de 5 éléments
    n dw 5                     ; Nombre d'éléments dans le tableau
    max dw 0                   ; Stocker le maximum

section .text
    global _start

_start:
    mov cx, [n]                ; Charger le nombre d'éléments dans CX
    mov esi, array             ; Pointeur sur le début du tableau
    mov ax, [esi]              ; Charger le premier élément du tableau dans AX
    mov [max], ax              ; Initialiser le maximum avec le premier élément
    add esi, 2                 ; Avancer dans le tableau

find_max_loop:
    cmp cx, 1                  ; Si CX = 1, il n'y a plus d'éléments à comparer
    je end_max                 ; Fin de la boucle si plus d'éléments

    mov bx, [esi]              ; Charger l'élément suivant du tableau
    cmp [max], bx              ; Comparer avec le maximum actuel
    jge no_update              ; Si le maximum est plus grand ou égal, pas besoin de mettre à jour

    mov [max], bx              ; Sinon, mettre à jour le maximum

no_update:
    add esi, 2                 ; Avancer au prochain élément du tableau
    loop find_max_loop         ; Décrémenter CX et continuer la boucle

end_max:
    ; Le maximum est maintenant stocké dans [max]

    ; Sortie du programme
    mov eax, 60                ; Code système pour exit
    xor edi, edi               ; Retourner 0
    syscall

Explication :

  • mov [max], ax : Initialise le maximum avec le premier élément du tableau.
  • cmp [max], bx : Compare l’élément courant du tableau avec le maximum actuel.
  • jge no_update : Si le maximum actuel est plus grand ou égal à l’élément, on ne le met pas à jour.
  • loop find_max_loop : Décrémente CX et répète la boucle pour vérifier tous les éléments.

Exercice 8 : Division d’un nombre avec gestion du reste

Contexte :

Écrire un programme en assembleur qui divise deux nombres et stocke le quotient et le reste dans des registres séparés.

Correction (x86) :

section .data
    dividend dw 25         ; Dividende
    divisor dw 4           ; Diviseur
    quotient dw 0          ; Quotient
    remainder dw 0         ; Reste

section .text
    global _start

_start:
    mov ax, [dividend]      ; Charger le dividende dans AX
    mov dx, 0               ; Initialiser DX à 0 (nécessaire pour la division)
    mov bx, [divisor]       ; Charger le diviseur dans BX

    div bx                  ; Diviser DX:AX par BX (quotient dans AX, reste dans DX)

    mov [quotient], ax       ; Stocker le quotient dans "quotient"
    mov [remainder], dx      ; Stocker le reste dans "remainder"

    ; Sortie du programme
    mov eax, 60             ; Code système pour exit
    xor edi, edi            ; Retourner 0
    syscall

Explication :

  • mov ax, [dividend] et mov bx, [divisor] : Charger les valeurs du dividende et du diviseur.
  • div bx : Divise AX par BX, stockant le quotient dans AX et le reste dans DX.
  • mov [quotient], ax : Stocker le quotient dans la mémoire.
  • mov [remainder], dx : Stocker le reste dans la mémoire.

Exercice 9 : Échange de deux nombres dans un tableau

Contexte :

Écrire un programme en assembleur qui échange deux éléments dans un tableau. Les indices des éléments à échanger sont stockés en mémoire.

Correction (x86) :

section .data
    array dw 10, 20, 30, 40, 50   ; Tableau de 5 éléments
    index1 dw 1                   ; Premier index (élément à la position 1)
    index2 dw 3                   ; Deuxième index (élément à la position 3)

section .text
    global _start

_start:
    mov si, [index1]              ; Charger le premier index dans SI
    shl si, 1                     ; Multiplier l'index par 2 (car chaque élément est un mot)
    mov di, [index2]              ; Charger le deuxième index dans DI
    shl di, 1                     ; Multiplier l'index par 2

    mov ax, [array + si]          ; Charger l'élément à l'index 1 dans AX
    mov bx, [array + di]          ; Charger l'élément à l'index 3 dans BX

    ; Échanger les valeurs
    mov [array + si], bx          ; Mettre l'élément 3 à la place de l'élément 1
    mov [array + di], ax          ; Mettre l'élément 1 à la place de l'élément 3

    ; Sortie du programme
    mov eax, 60                   ; Code système pour exit
    xor edi, edi                  ; Retourner 0
    syscall

Explication :

  • mov si, [index1] et mov di, [index2] : Charger les indices des éléments à échanger.
  • shl si, 1 et shl di, 1 : Multiplier les indices par 2 pour obtenir les bons décalages (chaque élément est un mot de 2 octets).
  • mov ax, [array + si] : Charger l’élément à l’index 1, et mov bx, [array + di] fait de même pour l’élément à l’index 3.
  • Échange des valeurs en stockant les éléments dans les nouvelles positions.

Exercice 10 : Copie d’une chaîne de caractères

Contexte :

Écrire un programme en assembleur qui copie une chaîne de caractères d’un emplacement mémoire à un autre jusqu’à atteindre la fin de la chaîne (0x00).

Voici la suite et fin de l’Exercice 10 : Copie d’une chaîne de caractères en assembleur :


Correction :
    inc edi                       ; Passer au caractère suivant dans la destination
    jmp copy_loop                 ; Répéter la boucle pour copier le caractère suivant

end_copy:
    ; Sortie du programme
    mov eax, 60                   ; Code système pour exit
    xor edi, edi                  ; Retourner 0
    syscall

Explication :

  • mov al, [esi] : Charge le caractère courant de la chaîne source.
  • mov [edi], al : Copie ce caractère à l’emplacement désigné par edi dans la chaîne destination.
  • test al, al : Vérifie si le caractère copié est le caractère nul (0x00), qui marque la fin de la chaîne.
  • inc esi et inc edi : Incrémentent les pointeurs pour passer aux caractères suivants dans les chaînes source et destination respectivement.
  • jmp copy_loop : Répète la boucle jusqu’à ce que la fin de la chaîne soit atteinte (lorsque le caractère nul est rencontré).

Résumé des cas particuliers abordés

Ces exercices illustrent divers cas particuliers dans la programmation en assembleur, notamment :

  1. Gestion du débordement lors d’additions.
  2. Multiplication de nombres signés avec gestion du signe.
  3. Calcul de la somme des carrés avec boucle.
  4. Conversion de chaînes hexadécimales en nombres binaires.
  5. Inversion des bits d’un nombre avec l’instruction not.
  6. Génération de séquence de Fibonacci en boucle.
  7. Recherche du maximum dans un tableau avec comparaison.
  8. Division de nombres avec gestion du reste.
  9. Échange de deux éléments d’un tableau.
  10. Copie d’une chaîne de caractères en mémoire.

Ces exercices visent à renforcer la compréhension de la manipulation des registres, des pointeurs, des boucles, des conditions, et de la gestion de la mémoire en assembleur, tout en traitant des situations pratiques et courantes dans l’optimisation de bas niveau.


💻 Exercices Assembleur x86 corrigés

Une série progressive d’exercices pour comprendre les registres, les opérations arithmétiques, les conditions, les boucles, la mémoire et la pile en assembleur x86.

Une série progressive d’exercices pour comprendre les registres, les opérations arithmétiques, les conditions, les boucles, la mémoire et la pile en assembleur x86. Chaque activité associe un objectif, un exemple de code, une illustration du fonctionnement du processeur et une correction commentée.

🧠 Comprendre l’architecture x86 avant de commencer
Repères essentiels

Les principaux registres utilisés dans les exercices

Un registre représente une petite zone de stockage directement intégrée au processeur. L’assembleur x86 manipule ces registres pour effectuer des calculs, déplacer des données, comparer des valeurs ou gérer les appels de fonctions.

EAX
Accumulateur
EBX
Base
ECX
Compteur
EDX
Données
ESI
Source
EDI
Destination
ESP
Pile
EBP
Base de pile
Instruction x86
MOV EAX, 5
Décodage par le processeur
EAX contient la valeur 5
À retenir : l’instruction MOV copie une donnée vers une destination. Elle ne déplace pas physiquement la valeur hors de la source.
1️⃣ Exercice 1 — Charger et additionner deux valeurs
Niveau débutant

Énoncé

Écrire un programme assembleur x86 qui place la valeur 12 dans le registre EAX, la valeur 8 dans le registre EBX, puis additionne les deux nombres. Le résultat doit rester dans EAX.

État initial EAX = indéfini
EBX = indéfini
État attendu EAX = 20
EBX = 8
section .text
global _start

_start:
    mov eax, 12
    mov ebx, 8
    add eax, ebx
Étape 1
EAX ← 12
Étape 2
EBX ← 8
Étape 3
EAX ← EAX + EBX = 20
Correction commentée :

Les deux instructions MOV initialisent les registres. L’instruction ADD EAX, EBX additionne ensuite le contenu de EBX à celui de EAX. La destination étant EAX, le résultat final est enregistré dans ce registre.

2️⃣ Exercice 2 — Soustraction et résultat négatif
Niveau débutant

Énoncé

Placer la valeur 15 dans EAX, puis soustraire 21. Déterminer la valeur finale de EAX.

mov eax, 15
sub eax, 21
Calcul mathématique 15 − 21 = −6
Résultat signé EAX = -6
Correction :

L’instruction SUB EAX, 21 retire 21 du contenu de EAX. Dans une représentation signée sur 32 bits, le résultat correspond à −6. En représentation hexadécimale complément à deux, cette valeur peut apparaître sous la forme FFFFFFFA.

3️⃣ Exercice 3 — Comparer deux nombres avec CMP
Niveau intermédiaire

Énoncé

Comparer les valeurs 18 et 12. Placer 1 dans ECX lorsque la première valeur est supérieure, sinon placer 0.

mov eax, 18
mov ebx, 12
cmp eax, ebx
jg valeur_superieure

mov ecx, 0
jmp fin

valeur_superieure:
mov ecx, 1

fin:
CMP EAX, EBX
18 est supérieur à 12
JG exécute le saut
Correction commentée :

CMP effectue une soustraction logique sans conserver le résultat. Cette instruction modifie les indicateurs du registre d’état. L’instruction JG teste ensuite ces indicateurs et déclenche le saut lorsque la première valeur signée est strictement supérieure à la seconde.

4️⃣ Exercice 4 — Créer une boucle avec ECX
Niveau intermédiaire

Énoncé

Utiliser une boucle pour additionner successivement les nombres de 1 à 5. Le résultat final doit être stocké dans EAX.

mov eax, 0
mov ebx, 1
mov ecx, 5

boucle:
    add eax, ebx
    inc ebx
    loop boucle
Tour Valeur ajoutée EAX après addition ECX restant
1 1 1 4
2 2 3 3
3 3 6 2
4 4 10 1
5 5 15 0
Résultat :

Le registre EAX contient finalement 15. L’instruction LOOP décrémente automatiquement ECX, puis retourne à l’étiquette indiquée tant que ECX reste différent de zéro.

5️⃣ Exercice 5 — Parcourir un tableau en mémoire
Niveau intermédiaire

Énoncé

Calculer la somme des quatre valeurs du tableau 3, 5, 7, 9. Utiliser ESI comme pointeur vers les données.

section .data
tableau dd 3, 5, 7, 9

section .text
mov esi, tableau
mov ecx, 4
mov eax, 0

addition:
    add eax, [esi]
    add esi, 4
    loop addition
tableau + 0
3
tableau + 4
5
tableau + 8
7
tableau + 12
9
Chaque entier déclaré avec dd occupe quatre octets. Le pointeur ESI doit donc avancer de 4 octets à chaque tour.
Correction :

La notation [ESI] signifie que le programme lit la valeur stockée à l’adresse contenue dans ESI. Après quatre passages, la somme obtenue est 24.

6️⃣ Exercice 6 — Utiliser la pile avec PUSH et POP
Niveau intermédiaire

Énoncé

Placer successivement les valeurs 10 et 25 dans la pile, puis les récupérer dans EAX et EBX.

push 10
push 25

pop eax
pop ebx
Ordre d’empilement 10 est empilé en premier, puis 25.
Ordre de retrait 25 est retiré en premier, puis 10.
Sommet
25 → récupéré dans EAX
Dessous
10 → récupéré dans EBX
Correction :

La pile applique le principe LIFO : la dernière valeur empilée est la première retirée. Le registre EAX reçoit donc 25 et EBX reçoit 10.

📝 Exercices supplémentaires à résoudre
Entraînement autonome

Exercice A — Maximum

Comparer trois nombres et conserver le plus grand dans EAX.

Exercice B — Nombre pair

Tester si un entier est pair en utilisant une opération logique avec AND.

Exercice C — Factorielle

Calculer la factorielle de 5 à l’aide d’une boucle et de l’instruction IMUL.

Compétence Instructions à mobiliser Résultat attendu
Recherche du maximum CMP, JG, MOV La valeur maximale dans EAX
Test pair ou impair AND, CMP, JE 1 si pair, 0 si impair
Calcul d’une factorielle IMUL, DEC, JNZ 120 pour 5!
📌 Mémo des instructions x86 essentielles
Instruction Fonction Exemple
MOV Copier une valeur MOV EAX, 10
ADD Additionner ADD EAX, EBX
SUB Soustraire SUB EAX, 5
IMUL Multiplier des valeurs signées IMUL EAX, EBX
CMP Comparer deux valeurs CMP EAX, EBX
JMP Effectuer un saut inconditionnel JMP fin
JE Sauter si les valeurs sont égales JE egal
JG Sauter si la première valeur est supérieure JG maximum
PUSH Empiler une valeur PUSH EAX
POP Retirer une valeur de la pile POP EBX

⚙️ Exercices ARM Assembly corrigés

Une série progressive d’exercices corrigés pour comprendre les registres ARM, les opérations arithmétiques, les branchements conditionnels, l’accès à la mémoire, les tableaux et les sous-programmes. Les exemples peuvent servir d’introduction à ARM Cortex, Raspberry Pi, STM32 et aux systèmes embarqués.

🧠 Comprendre les registres ARM
Repères essentiels

Les registres les plus utilisés

L’architecture ARM repose largement sur l’utilisation des registres. Les données sont généralement chargées depuis la mémoire dans un registre avant d’être traitées, puis enregistrées à nouveau en mémoire lorsque cela devient nécessaire.

R0
Argument / résultat
R1
Argument
R2
Argument
R3
Argument
R4
Registre général
R5
Registre général
SP
Pointeur de pile
LR
Adresse de retour
MOV R0, #5
Décodage de l’instruction
R0 contient 5
À retenir : le symbole # indique généralement une valeur immédiate. L’instruction MOV R0, #5 place donc directement la valeur 5 dans le registre R0.
1️⃣ Exercice 1 — Additionner deux nombres
Niveau débutant

Énoncé

Placer la valeur 14 dans R0, la valeur 6 dans R1, puis enregistrer leur somme dans R2.

Registres de départ R0 = 14
R1 = 6
Résultat attendu R2 = 20
MOV R0, #14
MOV R1, #6
ADD R2, R0, R1
Correction commentée :

L’instruction ADD R2, R0, R1 additionne le contenu de R0 et de R1. Le résultat est placé dans R2, tandis que les valeurs de départ restent disponibles.

2️⃣ Exercice 2 — Soustraire deux valeurs
Niveau débutant

Énoncé

Charger la valeur 25 dans R0, puis retirer 9. Le résultat doit être enregistré dans R1.

MOV R0, #25
SUB R1, R0, #9
Calcul réalisé 25 − 9 = 16
État final R1 = 16
Correction :

L’instruction SUB utilise ici trois opérandes. Le premier correspond au registre de destination, le deuxième à la valeur de départ et le troisième à la valeur soustraite.

3️⃣ Exercice 3 — Comparer deux nombres avec CMP
Niveau intermédiaire

Énoncé

Comparer les valeurs stockées dans R0 et R1. Placer 1 dans R2 lorsque R0 est supérieur à R1, sinon placer 0.

MOV R0, #18
MOV R1, #12

CMP R0, R1
BGT superieur

MOV R2, #0
B fin

superieur:
MOV R2, #1

fin:
CMP R0, R1
18 est supérieur à 12
BGT effectue le branchement
Correction commentée :

CMP compare les deux registres en mettant à jour les indicateurs du processeur. L’instruction BGT déclenche ensuite un branchement lorsque la première valeur signée est strictement supérieure à la seconde.

4️⃣ Exercice 4 — Créer une boucle avec un branchement
Niveau intermédiaire

Énoncé

Calculer la somme des nombres de 1 à 5. Utiliser R0 comme accumulateur et R1 comme compteur.

MOV R0, #0
MOV R1, #1

boucle:
    ADD R0, R0, R1
    ADD R1, R1, #1
    CMP R1, #6
    BNE boucle
Tour Valeur ajoutée Valeur de R0 Valeur suivante de R1
1 1 1 2
2 2 3 3
3 3 6 4
4 4 10 5
5 5 15 6
Résultat :

Le registre R0 contient finalement 15. La boucle continue tant que R1 reste différent de 6.

5️⃣ Exercice 5 — Charger une valeur depuis la mémoire
Niveau intermédiaire

Énoncé

Charger une valeur déclarée en mémoire dans le registre R1, puis lui ajouter 5.

.data
nombre:
    .word 12

.text
LDR R0, =nombre
LDR R1, [R0]
ADD R1, R1, #5
nombre
12
R0
adresse de nombre
R1
12, puis 17
LDR R0, =nombre charge l’adresse de la donnée, tandis que LDR R1, [R0] lit la valeur située à cette adresse.
Correction :

Le premier LDR prépare l’accès à la mémoire. Le deuxième récupère la valeur 12. L’instruction ADD produit ensuite le résultat final : R1 = 17.

6️⃣ Exercice 6 — Parcourir un tableau ARM
Niveau avancé

Énoncé

Calculer la somme des quatre valeurs du tableau 4, 7, 2, 9. Utiliser un registre comme pointeur et un autre comme compteur.

.data
tableau:
    .word 4, 7, 2, 9

.text
LDR R0, =tableau
MOV R1, #4
MOV R2, #0

boucle_tableau:
    LDR R3, [R0], #4
    ADD R2, R2, R3
    SUBS R1, R1, #1
    BNE boucle_tableau
tableau + 0
4
tableau + 4
7
tableau + 8
2
tableau + 12
9
Correction commentée :

L’instruction LDR R3, [R0], #4 lit la valeur pointée par R0, puis avance automatiquement le pointeur de quatre octets. La somme finale stockée dans R2 vaut 22.

7️⃣ Exercice 7 — Appeler un sous-programme
Niveau avancé

Énoncé

Créer un sous-programme qui additionne les valeurs contenues dans R0 et R1, puis renvoie le résultat dans R0.

MOV R0, #8
MOV R1, #11
BL addition
B fin

addition:
    ADD R0, R0, R1
    BX LR

fin:
BL addition
LR mémorise l’adresse de retour
BX LR revient au programme
Correction :

L’instruction BL appelle le sous-programme et enregistre l’adresse de retour dans LR. L’instruction BX LR permet ensuite de reprendre l’exécution après l’appel. Le résultat final vaut 19.

📝 Exercices ARM supplémentaires à résoudre
Entraînement autonome

Exercice A — Nombre pair

Tester si une valeur est paire en utilisant l’instruction AND.

Exercice B — Maximum

Comparer trois nombres et conserver la valeur maximale dans R0.

Exercice C — Factorielle

Calculer la factorielle de 5 avec une boucle et l’instruction MUL.

📌 Mémo des instructions ARM essentielles
Instruction Fonction Exemple
MOV Charger ou copier une valeur MOV R0, #10
ADD Additionner deux valeurs ADD R2, R0, R1
SUB Soustraire une valeur SUB R1, R0, #4
MUL Multiplier MUL R2, R0, R1
CMP Comparer deux valeurs CMP R0, R1
B Effectuer un branchement B fin
BEQ Brancher si les valeurs sont égales BEQ egal
BNE Brancher si elles sont différentes BNE boucle
LDR Charger une donnée depuis la mémoire LDR R1, [R0]
STR Enregistrer une donnée en mémoire STR R1, [R0]
BL Appeler un sous-programme BL addition
BX LR Revenir après un appel BX LR

🧩 Exercices Assembleur MIPS corrigés

Une série progressive d’exercices corrigés pour maîtriser les registres MIPS, les opérations arithmétiques, les branchements conditionnels, les boucles, les tableaux, la mémoire et les appels système. Les exemples sont compatibles avec les environnements pédagogiques MARS et QtSPIM.

🧠 Comprendre les registres MIPS
Repères essentiels

Les principaux registres utilisés

Le processeur MIPS utilise plusieurs catégories de registres. Certains servent à conserver des valeurs temporaires, d’autres à transmettre des paramètres, stocker des résultats ou gérer les appels de fonctions.

$t0
Temporaire
$t1
Temporaire
$s0
Sauvegardé
$s1
Sauvegardé
$a0
Argument
$v0
Résultat / syscall
$sp
Pointeur de pile
$ra
Adresse de retour
li $t0, 5
Décodage de l’instruction
$t0 contient 5
À retenir : l’instruction pseudo-MIPS li charge une valeur immédiate dans un registre. L’instruction la charge quant à elle une adresse mémoire.
1️⃣ Exercice 1 — Additionner deux nombres
Niveau débutant

Énoncé

Charger la valeur 12 dans le registre $t0, la valeur 8 dans $t1, puis enregistrer leur somme dans $t2.

Valeurs de départ $t0 = 12
$t1 = 8
Résultat attendu $t2 = 20
li $t0, 12
li $t1, 8
add $t2, $t0, $t1
Correction commentée :

L’instruction add $t2, $t0, $t1 additionne les contenus de $t0 et $t1. Le résultat est stocké dans $t2, sans modifier les deux registres de départ.

2️⃣ Exercice 2 — Soustraire deux valeurs
Niveau débutant

Énoncé

Charger la valeur 25 dans $t0 et la valeur 9 dans $t1. Enregistrer la différence dans $t2.

li $t0, 25
li $t1, 9
sub $t2, $t0, $t1
Calcul réalisé 25 − 9 = 16
État final $t2 = 16
Correction :

Le premier registre après l’instruction sub correspond à la destination. Le calcul effectué est donc $t2 = $t0 - $t1.

3️⃣ Exercice 3 — Comparer deux nombres
Niveau intermédiaire

Énoncé

Comparer les valeurs contenues dans $t0 et $t1. Placer 1 dans $t2 lorsque $t0 est supérieur à $t1, sinon placer 0.

li $t0, 18
li $t1, 12

bgt $t0, $t1, superieur

li $t2, 0
j fin

superieur:
li $t2, 1

fin:
$t0 = 18
$t1 = 12
Test avec BGT
$t2 reçoit 1
Correction commentée :

L’instruction pseudo-MIPS bgt effectue un branchement lorsque le premier opérande est strictement supérieur au second. Ici, la condition est vraie, donc le programme rejoint l’étiquette superieur.

4️⃣ Exercice 4 — Calculer une somme avec une boucle
Niveau intermédiaire

Énoncé

Calculer la somme des entiers de 1 à 5. Utiliser $t0 comme accumulateur et $t1 comme compteur.

li $t0, 0
li $t1, 1
li $t2, 6

boucle:
    add $t0, $t0, $t1
    addi $t1, $t1, 1
    bne $t1, $t2, boucle
Tour Valeur ajoutée Valeur de $t0 Valeur suivante de $t1
1 1 1 2
2 2 3 3
3 3 6 4
4 4 10 5
5 5 15 6
Résultat :

Le registre $t0 contient finalement 15. La boucle continue tant que $t1 reste différent de 6.

5️⃣ Exercice 5 — Lire une valeur en mémoire
Niveau intermédiaire

Énoncé

Charger la valeur déclarée sous l’étiquette nombre dans le registre $t0, puis lui ajouter 5.

.data
nombre: .word 12

.text
la $t1, nombre
lw $t0, 0($t1)
addi $t0, $t0, 5
nombre
12
$t1
adresse de nombre
$t0
12, puis 17
la charge une adresse dans un registre. L’instruction lw lit ensuite un mot de 32 bits à cette adresse.
Correction :

Le registre $t1 pointe vers la donnée. La commande lw $t0, 0($t1) récupère la valeur 12, puis addi produit le résultat final 17.

6️⃣ Exercice 6 — Parcourir un tableau
Niveau avancé

Énoncé

Calculer la somme des quatre valeurs du tableau 4, 7, 2, 9. Utiliser un registre comme pointeur et un autre comme compteur.

.data
tableau: .word 4, 7, 2, 9

.text
la $t0, tableau
li $t1, 4
li $t2, 0

boucle_tableau:
    lw $t3, 0($t0)
    add $t2, $t2, $t3
    addi $t0, $t0, 4
    addi $t1, $t1, -1
    bne $t1, $zero, boucle_tableau
tableau + 0
4
tableau + 4
7
tableau + 8
2
tableau + 12
9
Correction commentée :

Chaque mot déclaré avec .word occupe quatre octets. Le pointeur $t0 avance donc de quatre octets à chaque tour. La somme finale conservée dans $t2 vaut 22.

7️⃣ Exercice 7 — Afficher un entier avec syscall
Niveau intermédiaire

Énoncé

Afficher le nombre 42 dans la console avec un appel système MIPS.

li $v0, 1
li $a0, 42
syscall
Registre $v0 Le code 1 sélectionne l’affichage d’un entier.
Registre $a0 Il contient la valeur à afficher.
Correction :

Dans MARS et QtSPIM, le registre $v0 contient le numéro du service demandé. Le registre $a0 transporte ici l’entier transmis au service d’affichage.

8️⃣ Exercice 8 — Lire un entier saisi par l’utilisateur
Niveau intermédiaire

Énoncé

Demander au programme de lire un entier dans la console, puis transférer la valeur saisie dans le registre $t0.

li $v0, 5
syscall

move $t0, $v0
Correction commentée :

Le service numéro 5 lit un entier. Après l’appel système, la valeur saisie est disponible dans $v0. L’instruction move la copie dans $t0.

9️⃣ Exercice 9 — Créer une fonction MIPS
Niveau avancé

Énoncé

Créer une fonction qui additionne les valeurs transmises dans $a0 et $a1. Le résultat doit être renvoyé dans $v0.

li $a0, 8
li $a1, 11

jal addition
j fin

addition:
    add $v0, $a0, $a1
    jr $ra

fin:
JAL addition
$ra mémorise le retour
JR $ra reprend le programme
Correction :

L’instruction jal appelle la fonction et conserve l’adresse de retour dans $ra. L’instruction jr $ra permet ensuite de reprendre le programme principal. Le résultat renvoyé dans $v0 vaut 19.

📝 Exercices MIPS supplémentaires à résoudre
Entraînement autonome

Exercice A — Nombre pair

Tester si un entier est pair avec une opération logique andi.

Exercice B — Maximum

Comparer trois nombres et conserver le plus grand dans $t0.

Exercice C — Factorielle

Calculer la factorielle de 5 à l’aide d’une boucle et de l’instruction mul.

Compétence Instructions conseillées Résultat attendu
Tester un nombre pair andi, beq 1 si pair, 0 sinon
Rechercher un maximum bgt, move Valeur maximale dans $t0
Calculer une factorielle mul, addi, bne 120 pour 5!
📌 Mémo des instructions MIPS essentielles
Instruction Fonction Exemple
li Charger une valeur immédiate li $t0, 10
la Charger une adresse mémoire la $t0, tableau
add Additionner deux registres add $t2, $t0, $t1
addi Additionner une valeur immédiate addi $t0, $t0, 1
sub Soustraire deux registres sub $t2, $t0, $t1
mul Multiplier deux valeurs mul $t2, $t0, $t1
lw Charger un mot depuis la mémoire lw $t0, 0($t1)
sw Enregistrer un mot en mémoire sw $t0, 0($t1)
beq Brancher si deux valeurs sont égales beq $t0, $t1, egal
bne Brancher si deux valeurs diffèrent bne $t0, $zero, boucle
j Effectuer un saut direct j fin
jal Appeler une fonction jal calcul
jr $ra Revenir après un appel jr $ra
syscall Appeler un service système syscall

Les travaux pratiques en assembleur permettent de passer rapidement de la théorie à l’exécution réelle des instructions. Registres, opérations arithmétiques, comparaisons, boucles, pile et mémoire deviennent plus faciles à comprendre lorsqu’ils sont manipulés étape par étape. Cette série de TP corrigés s’accompagne de simulateurs interactifs pour tester des valeurs, observer le comportement du processeur et vérifier immédiatement les résultats obtenus. Elle convient aux étudiants, aux débutants en programmation bas niveau et à toute personne souhaitant progresser sur les architectures x86, ARM ou MIPS.

🧪 TP Assembleur corrigés et simulateurs interactifs

Des travaux pratiques progressifs pour manipuler les registres, exécuter des opérations, comprendre les comparaisons, simuler des boucles et suivre l’évolution de la mémoire. Chaque TP associe un énoncé, un code d’exemple, une correction et un mini-simulateur.

🧮 Simulateur de registres : MOV, ADD et SUB
Simulateur débutant

Exécuter une opération comme dans un processeur

Choisissez deux valeurs, sélectionnez une instruction puis observez le résultat stocké dans le registre de destination.

A
12
B
8
Résultat
20
ZF
0
ADD 12, 8 Résultat = 20 Zero Flag = 0
1️⃣ TP 1 — Additionner deux valeurs dans des registres
Niveau débutant

Objectif du TP

Charger deux nombres dans des registres, effectuer une addition et conserver le résultat dans un troisième registre.

Données Registre A = 14
Registre B = 6
Résultat attendu Registre C = 20
; Exemple x86
mov eax, 14
mov ebx, 6
add eax, ebx

; EAX contient maintenant 20
Correction commentée :

Les instructions MOV initialisent les registres. L’instruction ADD EAX, EBX ajoute ensuite le contenu de EBX à celui de EAX. Le résultat final reste dans EAX.

⚖️ Simulateur de comparaison : CMP et branchements
Simulateur intermédiaire

Tester une condition avant un saut

Ce simulateur reproduit le raisonnement d’une instruction CMP, suivie d’un branchement conditionnel.

CMP 18, 12 Condition testée : supérieur Branchement effectué : OUI
2️⃣ TP 2 — Trouver le plus grand de deux nombres
Niveau intermédiaire

Énoncé

Comparer les valeurs 25 et 17. Conserver la plus grande dans le registre EAX.

mov eax, 25
mov ebx, 17

cmp eax, ebx
jge fin

mov eax, ebx

fin:
Correction :

L’instruction CMP EAX, EBX compare les deux valeurs. Si EAX est supérieur ou égal, le programme rejoint directement l’étiquette fin. Dans le cas contraire, la valeur de EBX est copiée dans EAX.

🔁 Simulateur de boucle et accumulateur
Simulateur intermédiaire

Suivre chaque passage d’une boucle

Entrez une limite afin de calculer la somme des entiers de 1 jusqu’à cette valeur. Le simulateur affiche l’état du compteur et de l’accumulateur à chaque tour.

Tour 1 : somme = 1 Tour 2 : somme = 3 Tour 3 : somme = 6 Tour 4 : somme = 10 Tour 5 : somme = 15 Résultat final = 15
3️⃣ TP 3 — Calculer la somme des entiers de 1 à N
Niveau intermédiaire

Énoncé

Utiliser un compteur et un accumulateur pour calculer la somme des nombres de 1 à 5.

mov eax, 0
mov ebx, 1
mov ecx, 5

boucle:
    add eax, ebx
    inc ebx
    loop boucle
EAX Accumulateur de la somme
EBX Valeur ajoutée à chaque tour
ECX Nombre de tours restants
Résultat final :

Après cinq itérations, le registre EAX contient 15. L’instruction LOOP décrémente automatiquement ECX avant de vérifier si la boucle doit continuer.

🧠 Simulateur de parcours mémoire
Simulateur avancé

Calculer la somme d’un tableau

Entrez plusieurs entiers séparés par des virgules. Le simulateur reproduit la lecture successive des cases mémoire et l’avancement du pointeur.

Adresse +0 : valeur 4, somme = 4 Adresse +4 : valeur 7, somme = 11 Adresse +8 : valeur 2, somme = 13 Adresse +12 : valeur 9, somme = 22 Somme finale = 22
4️⃣ TP 4 — Parcourir un tableau en mémoire
Niveau avancé

Énoncé

Calculer la somme des quatre valeurs du tableau 4, 7, 2, 9.

section .data
tableau dd 4, 7, 2, 9

section .text
mov esi, tableau
mov ecx, 4
mov eax, 0

boucle_tableau:
    add eax, [esi]
    add esi, 4
    loop boucle_tableau
tableau + 0
4
tableau + 4
7
tableau + 8
2
tableau + 12
9
Chaque valeur déclarée avec dd occupe quatre octets. Le registre pointeur doit donc avancer de quatre octets après chaque lecture.
Correction :

Le registre ESI contient l’adresse de l’élément courant. La notation [ESI] lit la valeur stockée à cette adresse. La somme finale conservée dans EAX vaut 22.

🧩 Générateur de mini-TP Assembleur
Générateur d’entraînement

Créer un exercice aléatoire

Le générateur propose un nouvel exercice basé sur une opération, une comparaison, une boucle ou un tableau.

Cliquez sur « Générer un TP » pour commencer.
✅ Test rapide : êtes-vous prêt pour les TP ?
Autoévaluation

Question

Quelle instruction permet de comparer deux valeurs sans conserver directement le résultat de la soustraction ?

Sélectionnez une réponse.
AZ

Recent Posts

Marchand de biens immobiliers : activités, opérations, stratégies d’achat-revente et gestion des projets

Le métier de marchand de biens immobiliers consiste à acquérir des biens dans une logique…

5 heures ago

Plan de communication événement : exemple complet, méthode et modèle à télécharger

Le succès d'un événement se prépare bien avant l'ouverture des portes. Une communication structurée permet…

1 jour ago

Chromatographie HPLC : 20 exercices corrigés pour maîtriser les calculs et l’interprétation

La chromatographie liquide haute performance (HPLC) est aujourd'hui l'une des techniques analytiques les plus utilisées…

4 jours ago

HPLC : guide pratique du laboratoire, outils, simulateurs, calculs et interprétation des chromatogrammes

La HPLC (Chromatographie Liquide Haute Performance) est aujourd'hui l'une des techniques analytiques les plus utilisées…

1 semaine ago

Bilan prévisionnel sci gratuit : modèles Excel gratuits

Créer une SCI répond souvent à un projet de long terme. Certains souhaitent acquérir un…

1 semaine ago

Budget mariage : modèles Excel, calculateur, planning et guide complet

Organiser un mariage est une aventure aussi enthousiasmante qu'exigeante. Derrière chaque cérémonie réussie se cachent…

1 semaine ago

This website uses cookies.