TP n°: 4-5 - Assembly Language Programming Basics and Exercises

Ce TP introduit les bases de la programmation en langage assembleur, en particulier la gestion des segments de données, de la pile, des procédures, ainsi que l’utilisation des interruptions DOS pour l’entrée/sortie. Il propose plusieurs exercices pratiques pour manipuler des chaînes de caractères, des tableaux et des entrées clavier.

D'après le document TP n°: 4-5 - Assembly Language Programming Basics and Exercises

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

TP n°: 4-5 - Assembly Language Programming Basics and Exercises

Document source

Ce TP introduit les bases de la programmation en langage assembleur, en particulier la gestion des segments de données, de la pile, des procédures, ainsi que l’utilisation des interruptions DOS pour l’entrée/sortie. Il propose plusieurs exercices pratiques pour manipuler des chaînes de caractères, des tableaux et des entrées clavier. Pour réaliser ce TP, il est nécessaire de disposer d’un assembleur compatible 16 bits et d’un environnement DOS ou émulateur permettant l’exécution de programmes .EXE en assembleur.

Objectifs

  • Déclarer et initialiser des variables et tableaux dans le segment de données.
  • Définir et initialiser une pile en assembleur.
  • Écrire et appeler des procédures en assembleur.
  • Utiliser les interruptions DOS (INT 21h) pour l’affichage et la lecture clavier.
  • Manipuler des chaînes de caractères et des tableaux en mémoire.
  • Écrire des programmes simples pour afficher, lire et traiter des données en assembleur.

Prérequis et configuration

  • Connaissances de base en langage assembleur 16 bits (x86).
  • Compréhension des segments mémoire : DATA, CODE, STACK.
  • Environnement DOS ou émulateur (ex : DOSBox) pour exécuter les programmes.
  • Assembleur compatible (ex : MASM, TASM) pour assembler les sources.
  • Utilisation de l’interruption 21h pour les fonctions d’entrée/sortie.

Déclaration des données

La première étape consiste à déclarer les variables utilisées dans le programme dans un segment de données nommé Data SEGMENT. Chaque variable doit être nommée, avoir une taille et éventuellement une valeur initiale.

Règles pour les noms :

  • Composés uniquement de lettres, chiffres ou underscore (_).
  • Doivent commencer par une lettre.
  • Longueur maximale de 8 caractères.

Les tailles sont définies par des pseudo-instructions :

  • DB : Declare Byte (1 octet)
  • DW : Declare Word (2 octets)
  • DD : Declare Double (4 octets)

La valeur initiale peut être donnée ou remplacée par ? si non initialisée.

Exemples :

AGE DB ?          ; variable AGE, 1 octet, non initialisée
LETTRE DB 'A'      ; variable LETTRE initialisée à 'A' (65)
PHRASE DB 'BONJOUR$' ; chaîne de caractères terminée par '$' pour affichage

Pour déclarer un tableau, on utilise la pseudo-instruction DUP qui répète une valeur plusieurs fois :

tab1 DB 10 DUP (0)      ; tableau de 10 octets initialisés à 0
tab3 DW 100 DUP (?)      ; tableau de 100 mots non initialisés

Après la déclaration, il faut initialiser le registre DS pour pointer vers ce segment :

ASSUME DS:Data
MOV AX, Data
MOV DS, AX

Déclaration et initialisation de la pile

La pile est déclarée dans un segment spécial avec le mot-clé STACK :

Pile SEGMENT STACK
DW 80 DUP (?)    ; réserve 80 mots pour la pile
Pile ENDS

Pour utiliser la pile, il faut initialiser les registres SS et SP :

ASSUME SS:Pile
MOV AX, Pile
MOV SS, AX       ; initialisation du segment pile
; SP est initialisé automatiquement ou doit être positionné au sommet de la pile

Déclaration et appel d’une procédure

Une procédure est un bloc d’instructions regroupées entre une étiquette et les mots-clés PROC et ENDP. Le mot-clé near indique que la procédure est dans le même segment que le programme appelant.

Structure d’une procédure :

NomProc PROC near
  ; instructions
  RET
NomProc ENDP

Pour appeler une procédure, on utilise l’instruction CALL suivie du nom de la procédure :

CALL NomProc

Exercice 1 : Affichage d’un message

Objectif : Afficher le message « BONJOUR » sur l’écran selon deux méthodes :

1. Affichage d’une chaîne de caractères

Déclarer dans le segment de données une chaîne « Message » initialisée par 'BONJOUR$'. Utiliser la fonction 09h de l’interruption 21h pour afficher la chaîne.

Procédure :

  • Initialiser DS.
  • Charger l’adresse de la chaîne dans DX.
  • Mettre 09h dans AH.
  • Appeler INT 21h.
MOV AX, Data
MOV DS, AX
LEA DX, Message
MOV AH, 09h
INT 21h

La chaîne doit être terminée par le caractère '$' pour que l’affichage s’arrête correctement.

2. Affichage caractère par caractère

Déclarer la chaîne « Message » sans le caractère '$'. Utiliser la fonction 06h de l’interruption 21h pour afficher un caractère à la fois.

Procédure :

  • Initialiser DS.
  • Utiliser BX comme pointeur vers le début de la chaîne.
  • Utiliser CX comme compteur du nombre de caractères.
  • Dans une boucle, charger le caractère pointé par BX dans DL, mettre 06h dans AH, appeler INT 21h.
  • Incrémenter BX, décrémenter CX jusqu’à zéro.
MOV AX, Data
MOV DS, AX
MOV BX, OFFSET Message
MOV CX, LENGTH
BoucleAffichage:
  MOV DL, [BX]
  MOV AH, 06h
  INT 21h
  INC BX
  LOOP BoucleAffichage

Exercice 2 : Acquisition des caractères du clavier

Objectif : Lire des caractères au clavier et les stocker dans un buffer en mémoire jusqu’à ce que l’utilisateur appuie sur RETURN ou ait saisi 30 caractères.

Procédure :

  • Déclarer un buffer dans le segment de données.
  • Initialiser DS.
  • Utiliser BX pour pointer vers le début du buffer.
  • Utiliser CX pour compter le nombre de caractères lus.
  • Dans une boucle, appeler la fonction 01h de l’interruption 21h pour lire un caractère avec écho.
  • Stocker le caractère dans le buffer pointé par BX, incrémenter BX et CX.
  • Arrêter la boucle si le caractère est RETURN (code 0Dh) ou si CX atteint 30.
MOV AX, Data
MOV DS, AX
MOV BX, OFFSET Buffer
MOV CX, 0
BoucleLecture:
  MOV AH, 01h
  INT 21h
  CMP AL, 0Dh
  JE FinLecture
  MOV [BX], AL
  INC BX
  INC CX
  CMP CX, 30
  JL BoucleLecture
FinLecture:

À la fin, BX contient l’adresse de départ du buffer, CX le nombre de caractères lus.

Exercice 3 : Manipulation de tableaux

Définir dans le segment de données un tableau TAB1 initialisé avec les valeurs 4, 7, 3 et 6, et réserver un tableau TAB2 de même taille.

1. Remplir TAB2 avec des valeurs lues au clavier et les afficher

Procédure :

  • Lire 4 caractères au clavier avec la fonction 01h (INT 21h), stocker dans TAB2.
  • Afficher chaque caractère avec la fonction 02h (INT 21h).
MOV AX, Data
MOV DS, AX
MOV SI, OFFSET TAB2
MOV CX, 4
LireBoucle:
  MOV AH, 01h
  INT 21h
  MOV [SI], AL
  MOV DL, AL
  MOV AH, 02h
  INT 21h
  INC SI
  LOOP LireBoucle

2. Recopier TAB1 en ordre inverse dans TAB2

Procédure :

  • Initialiser SI à la fin de TAB1.
  • Initialiser DI au début de TAB2.
  • Copier les éléments de TAB1 dans TAB2 en décrémentant SI et incrémentant DI.
MOV SI, OFFSET TAB1 + 3    ; dernier élément (index 3)
MOV DI, OFFSET TAB2
MOV CX, 4
CopieBoucle:
  MOV AL, [SI]
  MOV [DI], AL
  DEC SI
  INC DI
  LOOP CopieBoucle

3. Afficher TAB1 et trouver le minimum

Procédure :

  • Afficher chaque élément de TAB1 avec la fonction 02h.
  • Comparer les éléments pour trouver le minimum et le stocker dans AX.
MOV SI, OFFSET TAB1
MOV CX, 4
MOV AL, [SI]
MOV AH, 0
MOV AX, AX          ; AX contient le premier élément
INC SI
DEC CX
MinBoucle:
  MOV BL, [SI]
  CMP BL, AL
  JAE Skip
  MOV AL, BL
Skip:
  MOV DL, [SI]
  MOV AH, 02h
  INT 21h
  INC SI
  LOOP MinBoucle
MOV AX, AL

4. Trouver le maximum et l’afficher avec un message

Procédure :

  • Parcourir TAB1 pour trouver le maximum et le stocker dans BX.
  • Afficher le message « LE MAX EST : » suivi du maximum.
MOV SI, OFFSET TAB1
MOV CX, 4
MOV BL, [SI]
INC SI
DEC CX
MaxBoucle:
  MOV AL, [SI]
  CMP AL, BL
  JBE SkipMax
  MOV BL, AL
SkipMax:
  INC SI
  LOOP MaxBoucle
MOV BX, BL

; Affichage du message
LEA DX, MessageMax
MOV AH, 09h
INT 21h

; Affichage du maximum (en DL)
MOV DL, BL
MOV AH, 02h
INT 21h

Résultats attendus

  • Affichage correct des chaînes et caractères selon les méthodes choisies.
  • Lecture correcte des caractères clavier jusqu’à RETURN ou 30 caractères.
  • Remplissage et affichage des tableaux conforme aux valeurs saisies ou initialisées.
  • Recopie inverse correcte de TAB1 dans TAB2.
  • Identification correcte du minimum et du maximum dans TAB1.
  • Affichage du message et des valeurs numériques sans erreur.

Pièges courants

  • Oublier de terminer une chaîne destinée à l’affichage par le caractère '$' pour la fonction 09h.
  • Ne pas initialiser correctement les registres de segments (DS, SS) avant utilisation.
  • Confondre les registres utilisés comme pointeurs (BX, SI, DI) et compteurs (CX).
  • Ne pas gérer correctement la fin de chaîne ou le compteur dans les boucles d’affichage ou de lecture.
  • Oublier d’utiliser RET à la fin d’une procédure.
  • Ne pas sauvegarder/restaurer les registres si nécessaire lors d’appels de procédures.
  • Utiliser une taille incorrecte pour les tableaux ou les variables (DB vs DW vs DD).
  • Ne pas vérifier les codes ASCII pour les caractères spéciaux (ex : RETURN = 0Dh).

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions