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.

Autres articles

Exercices de Programmation Corrigés sur le Microprocesseur...
Le microprocesseur Motorola 6809 est un processeur 8 bits très...
Read more
Programmation ISO (ou G-code) : Guide
La programmation ISO (ou G-code) est un langage standard utilisé...
Read more
Exercices Corrigés Programmation ISO en tournage CNC
Voici une série d'exercices corrigés sur la programmation ISO en...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *