data SEGMENT msg db "Bonne chance",'$' ; Message à afficher data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX ; Initialiser BL à 0 pour compter jusqu'à 10 MOV BL, 0 boucle: ; Incrémenter le compteur BL INC BL ; Comparer BL avec 10 CMP BL, 10 ; Appel de la procédure "afficher" CALL afficher ; Répéter tant que BL != 10 JNE boucle ; Fin du programme MOV AH, 4CH INT 21H afficher PROC near ; Afficher le message "Bonne chance" MOV DX, offset msg MOV AH, 09H INT 21H ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Retour à l'appelant RET afficher ENDP code ENDS END debut
Procédures
Série
Comment déclarer une procédure
data SEGMENT ; Déclarations des données (aucune donnée pour le moment) data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX ; Appel de la procédure CALL example_procedure ; Terminaison du programme MOV AH, 4Ch INT 21h example_procedure PROC NEAR ; Instructions à exécuter dans la procédure (vide pour l'instant) RET ; Retour à l'appelant example_procedure ENDP code ENDS END debut
Exercice 1
- Ecrire un programme assembleur qui affiche le message « bonne chance » 10 fois. Les messages doivent être écrit un par ligne. Utiliser une procédure « affiche » af qui permet l’affichage.
Correction
Exercice 2
- Ecrire un programme assembleur qui permet d’afficher le message «bonne chance$» autant de fois qu’on veut. Les messages doivent être écrits un par ligne. Utiliser une procédure « affiche » qui permet l’affichage.
Correction
data SEGMENT msg_chance db "Bonne chance",'$' ; Message à afficher msg_entrer db "Entrer un entier : ",'$' ; Message pour demander un entier data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX ; Afficher le message "Entrer un entier" MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Lire un caractère (entier saisi par l'utilisateur) MOV AH, 01H INT 21H MOV BL, AL ; Sauvegarder le caractère lu dans BL ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02H INT 21H ; Initialiser le compteur CL à '0' MOV CL, '0' boucle: ; Incrémenter le compteur INC CL ; Appeler la procédure afficher CALL afficher ; Comparer CL avec BL (entier saisi) CMP CL, BL JNE boucle ; Continuer si CL != BL ; Terminaison du programme MOV AH, 4CH INT 21H afficher PROC near ; Afficher le message "Bonne chance" MOV DX, offset msg_chance MOV AH, 09H INT 21H ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02H INT 21H ; Retourner à l'appelant RET afficher ENDP code ENDS END debut
Exercice 3
- Ecrire un programme assembleur qui permet de lire et d’afficher 20 caractères. Utiliser une procédure « lire-affiche » qui permet de lire et d’afficher un caractère.
Correction
data SEGMENT msg_entrer db "Entrer un caractere : ",'$' ; Message d'invite msg_lu db "Le caractere lu est : ",'$' ; Message pour afficher le caractère lu data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX ; Initialiser le compteur CL à 0 MOV CL, 0 boucle: ; Afficher le message "Entrer un caractere" MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Appeler la procédure pour lire et afficher le caractère CALL lire_affiche ; Incrémenter le compteur et vérifier la limite INC CL CMP CL, 20 JNE boucle ; Terminaison du programme MOV AH, 4CH INT 21H lire_affiche PROC near ; Lire un caractère de l'utilisateur MOV AH, 01H INT 21H MOV BL, AL ; Sauvegarder le caractère lu dans BL ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Afficher le message "Le caractere lu est" MOV DX, offset msg_lu MOV AH, 09H INT 21H ; Afficher le caractère lu MOV DL, BL MOV AH, 02H INT 21H ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Retour à l'appelant RET lire_affiche ENDP code ENDS END debut
Exercice 4
- Ecrire un programme assembleur qui permet de lire et d’afficher des caractères tant que le caractère est différent de ‘?’. Utiliser une procédure « lire-affiche » qui permet de lire et d’afficher un caractère.
Correction
data SEGMENT msg_entrer DB "Entrer un caractere : ",'$' ; Message d'invite msg_lu DB "Caractere lu est : ",'$' ; Message pour afficher le caractère lu data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX boucle: ; Afficher le message "Entrer un caractere" MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Appeler la procédure pour lire et afficher le caractère CALL lire_affiche ; Le caractère lu est placé dans BL ; Comparer BL avec le caractère '?' CMP BL, '?' JNE boucle retourne: ; Terminaison du programme MOV AH, 4CH INT 21H lire_affiche PROC near ; Lire un caractère de l'utilisateur MOV AH, 01H INT 21H MOV BL, AL ; Sauvegarder le caractère lu dans BL ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Vérifier si le caractère lu est '?' pour sortir immédiatement CMP BL, '?' JE retourne ; Afficher le message "Caractere lu est" MOV DX, offset msg_lu MOV AH, 09H INT 21H ; Afficher le caractère lu MOV DL, BL MOV AH, 02H INT 21H ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Retourner à l'appelant RET lire_affiche ENDP code ENDS END debut
Exercice 5
- Ecrire un programme assembleur qui permet de lire 10 chaînes de caractères. Utiliser une procédure « lire-chaîne » qui permet la lecture d’une chaîne de caractères.
Correction
data SEGMENT msg_entrer DB "Entrer une chaine : ",'$' ; Message d'invite chaine db 20 dup('?'), '$' ; Réserve 20 caractères, initialisés à '?' avec un terminateur '$' msg_lu DB "Chaine lu est : ",'$' ; Message pour afficher la chaîne lue data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX ; Initialiser le compteur CL à 0 MOV CL, 0 boucle: ; Afficher le message "Entrer une chaine" MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Appeler la procédure pour lire une chaîne CALL lire_chaine ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Afficher le message "Chaine lu est" MOV DX, offset msg_lu MOV AH, 09H INT 21H ; Afficher la chaîne saisie (débutant après les deux premiers octets) MOV DX, offset chaine + 2 MOV AH, 09H INT 21H ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Incrémenter le compteur et vérifier si la limite (10) est atteinte INC CL CMP CL, 10 JNE boucle ; Terminaison du programme MOV AH, 4CH INT 21H lire_chaine PROC near ; Lire une chaîne saisie par l'utilisateur MOV DX, offset chaine MOV AH, 0AH INT 21H ; La chaîne saisie est stockée dans `chaine`, après deux octets (longueur max et effective) RET lire_chaine ENDP code ENDS END debut
Exercice 6
- Ecrire un programme assembleur qui permet de lire des chaînes de caractères autant de fois qu’on veut. Utiliser une procédure « lire_chaine » qui permet la lecture d’une chaîne de caractères.
Correction
data SEGMENT chaine db 20 dup('?'), '$' ; Zone mémoire pour la chaîne avec un terminateur `$` msg_entier db "Entrer un entier : ",'$' ; Message pour demander un entier msg_chaine db "Entrer une chaine : ",'$' ; Message pour demander une chaîne punctuation db ": ",'$' ; Séparateur utilisé dans l'affichage data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialiser le segment de données MOV AX, data MOV DS, AX ; Afficher le message "Entrer un entier" MOV DX, offset msg_entier MOV AH, 09H INT 21H ; Lire un caractère (l'entier) et le conserver dans BL MOV AH, 01H INT 21H MOV BL, AL ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Initialiser le compteur CL à '0' MOV CL, '0' boucle: ; Incrémenter le compteur CL INC CL ; Afficher le message "Entrer une chaine" MOV DX, offset msg_chaine MOV AH, 09H INT 21H ; Appeler la procédure pour lire la chaîne CALL lire_chaine ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Afficher le numéro (CL) MOV DL, CL MOV AH, 02H INT 21H ; Afficher le séparateur ": " MOV DX, offset punctuation MOV AH, 09H INT 21H ; Afficher la chaîne saisie (débutant après les deux premiers octets) MOV DX, offset chaine + 2 MOV AH, 09H INT 21H ; Ajouter un saut de ligne MOV DL, 0AH MOV AH, 02H INT 21H ; Vérifier si le compteur CL atteint l'entier BL CMP CL, BL JNE boucle ; Terminaison du programme MOV AH, 4CH INT 21H lire_chaine PROC near ; Lire une chaîne saisie par l'utilisateur MOV DX, offset chaine MOV AH, 0AH INT 21H ; La chaîne saisie est stockée dans `chaine` après deux octets RET lire_chaine ENDP code ENDS END debut
Exercice supplémentaire 1
- Ecrivez un programme en assembleur qui demande à l'utilisateur d'entrer 'o' ou 'O' s'il veut que le programme affiche « bonne chance ».
- Pour faire passer un caractère de minuscule à majuscule, il faut forcer le sixième bit à 0. Exemple :
- Pour faire passer un caractère de majuscule à miscule, il faut forcer le sixième bit à 1. Exemple :
- Si vous avez des questions, vous pouvez les poser à l'assistant IA.
Indication
MOV AL, 'o' ; Charge le caractère 'o' (ASCII 111) dans le registre AL AND AL, 11011111b ; Forcer le 6ᵉ bit à 0 pour convertir en majuscule
MOV AL, 'O' ; Charge le caractère 'o' (ASCII 111) dans le registre AL OR AL, 00100000b ; Forcer le 6ᵉ bit à 1 pour convertir en miniscule
Correction
data SEGMENT msg_chance db "Bonne chance",'$' ; Message "Bonne chance" msg_entrer db "Afficher 'Bonne chance'? Entrer 'O' si oui : ",'$' ; Message pour demander une confirmation data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialisation du segment de données MOV AX, data MOV DS, AX boucle: ; Afficher le message d'invite MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Lire un caractère de l'utilisateur MOV AH, 01H INT 21H ; Convertir le caractère en majuscule MOV BL, AL AND BL, 11011111b ; Vérifier si le caractère est 'O' CMP BL, 'O' JNE fin ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02H INT 21H ; Appeler la procédure pour afficher "Bonne chance" CALL afficher JMP boucle fin: ; Terminaison du programme MOV AH, 4CH INT 21H afficher PROC near ; Afficher le message "Bonne chance" MOV DX, offset msg_chance MOV AH, 09H INT 21H ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02H INT 21H ; Retourner à l'appelant RET afficher ENDP code ENDS END debut
Exercice supplémentaire 2 (DIFFICILE)
- Écrire un programme en assembleur qui demande à l'utilisateur de saisir « oui » , « Oui », « OUi », s'il veut que le programme affiche « bonne chance ». Créer une procédure qui lire le reponse d'utilisateur et vérifie si le reponse est égale à « oui$ ».
- Après avoir utilisé la fonction 0Ah, le msg + 1est la taille de la chaîne et la chaîne commence au msg + 2.
- Si vous avez des questions, vous pouvez les poser à l'assistant IA.
Indication
Correction
data SEGMENT ; Messages et buffers msg_entrer db "Afficher 'Bonne chance'? Entrer 'Oui' si oui : ",'$' msg_chance db "Bonne chance",'$' chaine_reponse db 10 dup('?'), '$' chaine_oui db "OUI",'$' data ENDS code SEGMENT ASSUME DS: data, CS: code debut: ; Initialiser le segment de données MOV AX, data MOV DS, AX boucle: ; Afficher le message d'invite MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Lire l'entrée utilisateur CALL lire_reponse ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02H INT 21H ; Afficher "Bonne chance" MOV DX, offset msg_chance MOV AH, 09H INT 21H ; Ajouter un saut de ligne supplémentaire MOV DL, 0AH MOV AH, 02H INT 21H JMP boucle fin: ; Terminer le programme MOV AH, 4Ch INT 21H lire_reponse PROC near ; Lire l'entrée utilisateur dans chaine_reponse MOV DX, offset chaine_reponse MOV AH, 0Ah INT 21H ; Appeler la procédure de vérification CALL verifier RET lire_reponse ENDP verifier PROC near ; Comparer la longueur de l'entrée MOV AL, [chaine_reponse + 1] CMP AL, 3 ; La longueur de "OUI" est 3 JNE fin ; Initialiser les pointeurs pour la comparaison MOV BX, offset chaine_reponse + 2 MOV SI, offset chaine_oui MOV CL, 0 boucle_comparer: ; Vérifier si les 3 caractères ont été comparés CMP CL, 3 JE egaux ; Charger et convertir un caractère de l'entrée utilisateur MOV AL, [BX] AND AL, 11011111b ; Charger et convertir un caractère de la chaîne de référence MOV AH, [SI] AND AH, 11011111b ; Comparer les caractères CMP AL, AH JNE FIN ; Incrémenter les pointeurs et le compteur INC BX INC SI INC CL JMP boucle_comparer egaux: RET verifier ENDP code ENDS END debut
Exercice supplémentaire 3 (IMPORTANTE)
- Donner le programme assembleur qui calcule la longueur d’une chaîne de caractères et qui renvoie le résultat dans le registre CX. La chaîne de caractères doit être lue. Utiliser deux procédures “Lire-chaîne” et “longueur_chaîne” qui permettent respectivement de lire la chaîne de caractères et calculer la longueur de chaîne de caractères.
Correction
data SEGMENT msg_entrer DB "Entrer une chaine : ",'$' msg_taille DB "Taille du chaine : ",'$' chaine DB 20 dup('?'), '$' data ENDS code SEGMENT ASSUME DS:data, CS:code debut: ; Initialiser le segment de données MOV AX, data MOV DS, AX ; Afficher le message d'invite MOV DX, offset msg_entrer MOV AH, 09H INT 21H ; Lire l'entrée utilisateur CALL lire_chaine ; Ajouter un saut de ligne MOV DL, 0Ah MOV AH, 02h INT 21h ; Calculer la longueur de la chaine CALL longueur_chaine ; Afficher le message de longueur MOV DX, offset msg_taille MOV AH, 09H INT 21H ; Afficher la longueur en ASCII MOV DL, CL MOV AH, 02H INT 21H ; Terminer le programme MOV AH, 4CH INT 21H lire_chaine PROC NEAR ; Lire une chaîne avec la fonction 0Ah MOV DX, offset chaine MOV AH, 0AH INT 21H RET lire_chaine ENDP longueur_chaine PROC NEAR ; Calculer la longueur de la chaîne (stockée dans [chaine + 1]) MOV CL, [chaine + 1] ADD CX, '0' ; Convertir en ASCII RET longueur_chaine ENDP code ENDS END debut