DEUXIEME PARTIE

PREMIER CONTACT AVEC LE LANGAGE ASSEMBLEUR



    I. PREMIER EXEMPLE : LES FICHIERS COM

Voici un petit programme COM qui écrit le message « Bonjour, monde ! » à l’écran.

Ce code source commence par des directives. Une directive est une information que le programmeur fournit au compilateur. Elle n’est pas transformée en une instruction en langage machine. Elle n’ajoute donc aucun octet au programme compilé.

La directive “.386“ indique au compilateur que le programme est destiné à tourner sur des processeurs INTEL de modèle 386 (ou supérieur). Cela nous autorise à utiliser certaines instructions qui ne sont pas disponibles sur les modèles antérieurs, comme PUSHA ou POPA. Dans cet exemple, cette directive aurait très bien pu être omise.

La ligne

code segment use16

sert à déclarer un segment que l’on appelle “code”. On aurait tout aussi bien pu le nommer “marteau” ou “voiture”. Ce sera le segment de notre programme. N’oubliez pas qu’un fichier COM ne peut comporter qu’un seul segment. Cette ligne ne sera pas compilée : elle ne sert qu’à indiquer au compilateur le début d’un segment.

Le mot “use16” indique que les adresses de segment et d’offset sont codées sur 16 bits et non sur 8 bits. Vous devez systématiquement l’écrire.

La directive

assume cs:code, ds:code, ss:code

informe le compilateur que tout au long du programme, CS, DS et SS pointeront de façon privilégiée vers le segment “code”, ce qui est évident d’ailleurs puisque c’est le seul segment… Vous comprendrez le sens exact de “assume” dans la troisième partie du cours.

Enfin, les mots

org 100h

signifient qu’il faudra ajouter 100h (soit 256) à tous les offsets. Pourquoi ? Souvenez-vous de la structure d’un programme COM en mémoire. Si vous n’écrivez pas cette ligne, TASM considérera que le programme débute à l’offset 0000. Or, lors de l’exécution, le DOS le chargera après le PSP, c’est-à-dire à l’adresse 100h. C’est pourquoi il est nécessaire de recalculer les offsets : l’offset 0000 deviendra 0100. Cette directive est en quelque sorte le trait caractéristique des fichiers COM.

Nous en arrivons au programme proprement dit. Il commence par un label :

debut :

Lui non plus n’est pas compilé. Il ne sert qu’à représenter l’adresse de l’instruction qui le suit, c’est-à-dire :

mov ah, 09h

Cette ligne demande au processeur de charger la valeur 9 dans le registre AH. C’est le numéro de la fonction de l’interruption 21h qui écrit une chaîne de caractères à l’écran. L’offset de cette chaîne est attendu dans DX. D’où la ligne suivante :

mov dx, offset message

Le mot-clé “offset” sert à extraire l’offset du label “message” qui représente quant à lui l’adresse du message à écrire (il contient donc une adresse de segment ET un offset). L’adresse de segment de la chaîne doit être transmise dans DS. Mais il est inutile de changer ce registre, car il pointe déjà vers notre segment.

Il nous reste à appeler l’interruption 21h :

int 21h

et à rendre la main au DOS :

ret

Lorsque nous aborderons les procédures, vous comprendrez mieux le sens de ce mot et ce qu’il fait exactement. Pour l’instant, sachez simplement que seul un fichier COM peut se terminer avec cette instruction.

Nous arrivons à la ligne :

message db “Bonjour, monde !”, ‘$

Il s’agit d’une définition de données. Le mot “db” (« define byte ») signifie que le compilateur devra écrire les octets qui suivent tels qu’ils sont dans notre code source. Il va donc écrire le code ASCII du ‘B’, puis celui du ‘o’, etc… Il terminera en écrivant le code ASCII du signe ‘$’. C’est ainsi que la fonction 9 de l’interruption 21h reconnaît la fin de la chaîne à écrire. Si vous oubliez ce signe, elle écrira tous les octets de la RAM jusqu’à ce qu’elle tombe par hasard sur lui.

Le mot “message” placé en début de ligne est un label de données. Il représente l’adresse du code ASCII du ‘B’. Remarquez qu’il n’y a pas de caractère ‘:’ après un label de données.

La ligne

code ends

indique la fin du segment “code”, et enfin

end debut

informe le compilateur que le fichier est fini, tout comme le “END.” du PASCAL. Le nom du label “debut” est mentionné : ce sera le point d’entrée de notre programme. C’est vers lui que pointera CS:IP avant l’exécution.

Remarque : vous n’êtes pas tenu de rendre aux registres la valeur qu’ils avaient au début de votre programme. De toute façon, avant de charger un programme, le DOS sauvegarde le contenu de tous les registres puis met le contenu des registres généraux (ainsi que SI, DI et BP) à zéro. Il les restaurera quand vous lui rendrez la main.



Sommaire

Suite