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.
Écrire un programme en assembleur qui additionne deux nombres, les charge dans les registres AX et BX, puis place le résultat dans CX.
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
É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.
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
Écrire un programme en assembleur qui additionne les nombres de 1 à 5 en utilisant une boucle, et place le résultat final dans AX.
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
É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.
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
É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.
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
É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 :
Écrire un programme en assembleur qui calcule la factorielle d’un nombre stocké en mémoire. Le résultat sera retourné dans AX.
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
Écrire un programme en assembleur qui utilise une interruption système pour afficher une chaîne de caractères à l’écran.
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
Écrire un programme en assembleur qui additionne deux tableaux de 5 éléments et stocke le résultat dans un troisième tableau.
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
Écrire un programme en assembleur qui incrémente un compteur jusqu’à une valeur donnée et arrête lorsque la valeur 10 est atteinte.
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
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.
É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.
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
É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.
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
É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.
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
É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.
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
É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.
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
Voici la suite et fin de l’Exercice 6 pour la génération de la séquence de Fibonacci en assembleur :
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
Écrire un programme en assembleur qui parcourt un tableau d’entiers et trouve le maximum. Le résultat doit être stocké dans un registre.
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
Écrire un programme en assembleur qui divise deux nombres et stocke le quotient et le reste dans des registres séparés.
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
É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.
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
É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 :
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
0x00
), qui marque la fin de la chaîne.Ces exercices illustrent divers cas particuliers dans la programmation en assembleur, notamment :
not
.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.
Les écarts sur charges fixes permettent d'analyser les différences entre les charges fixes budgétées et…
L’écart-type est une mesure de la dispersion des données autour de la moyenne. Excel propose…
Exercice 1 : Calcul des Écarts sur Volume et Prix Contexte :Une entreprise a prévu…
1. Généralités sur le Contrôle Budgétaire Question 1 : Quel est l’objectif principal du contrôle…
Voici un QCM Contrôle de Gestion - Pilotage de la Performance bien conçu sur le…
Une fiche d’action est un outil essentiel pour planifier, suivre et gérer les tâches dans…
This website uses cookies.