TD N°3 : Initiation à l’assembleur X86 Utilisation de l’outil DEBUG 1) L’objectif de cette séance de travaux dirigés n’est pas la programmation en langage assembleur, mais une familiarisation par la mise en pratique des notions qui ont a été vues en cours concernant la représentation des données et l’architecture de l’unité centrale d’un ordinateur. Nous nous bornerons à écrire et à exécuter quelques instructions en mode interactif sous le contrôle de l’outil DEBUG qui s’exécute sous Windows dans une fenêtre DOS . 2) Vous avez à votre disposition : a) un rapide descriptif de l’outil DEBUG et de ses principales commandes; lisez l’introduction, et ce qui concerne les commandes : R (register) qui donne le contenu des principaux registres du processeur, D (Dump) qui donne le contenu d’un block d’adresses mémoire, E (Enter) qui permet d’initialiser le contenu d’adresses mémoire, A (Assemble) qui permet d’écrire des instruction en assembleur (avec une syntaxe parfois particulière à l’outil DEBUG), U (Unassemble) qui permet de retrouver une instruction assembleur à partie d’une instruction en code machine (hexadécimal), G (Go) qui permet de lancer l’exéution d’un programme, T (Trace) qui permet d’exécuter les instruction pas à pas. b) une table décrivant les instructions X86 les plus courantes ; lisez plus particulièrement ce qui concerne les instructions que vous aurez à utiliser : MOV, ADD, SUB, MUL, DIV, NOT, NEG, JMP, INT c) une table donnant la correspondance entre les codes mnémoniques des instructions et leur valeur en langage machine (code hexadécimal). d) une table des codes ASCII. 3) Travail à réaliser : a) Complément à 2 Nous allons réaliser en pratique l’opération prise en exemple dans le cours pour illustrer la mise en œuvre du complément à 2. Utilisez la commande Display Register (R) pour afficher le contenu des différents registres. Utilisez ensuite l’instruction Move (MOV) pour charger la valeur décimale 73 dans la partie basse de l’accumulateur (AL). Pour cela vous passerez en mode Assemblage (A), puis vous entrerez l’instruction : MOV AL,49 Puis vous entrerez la commande trace (T) qui provoquera l’exécution de cette instruction et affichera le contenu des registres. Vous pourrez constater que le contenu de AL est bien devenu 49. En procédant d’une façon analogue, transférer le contenu de AL à l’adresse mémoire 200 hexadécimal. Afficher le contenu de cette adresse mémoire grâce à la commande D (Dump) et vérifiez qu’elle contient bien 49 hexadécimal. Toujours en procédant de la même manière, chargez 0 dans AL, puis ôtez lui la valeur contenu à l’adresse 200 hexadécimale. Affichez le contenu de AL. Que constatez vous ? Réalisez la même opération qu’à la question précédente en travaillant uniquement sur AL avec une valeur immédiate et en utilisant l’instruction NEG. b) Complément à 1 De la même façon qu’à la question précédente réaliser le complément à 1 de la valeur décimale 73 en remplaçant la soustraction par une fonction logique que vous devez déterminer. Puis comme précédemment réaliser la même fonction en travaillant uniquement sur AL avec une valeur immédiate et en utilisant la fonction NOT. c) Visualisation du contenu de la mémoire. Utilisez la commande Enter (E) pour initialiser les adresses mémoires 210 à 21F avec les valeurs hexadécimales suivantes : 49 55 50 2D 4D 49 41 47 45 20 20 20 20 20 20 26 Affichez le contenu de cette série d’adresses avec la commande DUMP (D) . Que constatez-vous ? Maintenant chargez en utilisant une suite de commandes move (MOV) avec donnée immédiate les adresses mémoire 220 à 22F avec les codes ASCII qui correspondent à votre nom (la recherche de ces codes a été faites lors de la séance de travaux dirigés précédente). Affichez le contenu de cette série d’adresses avec la commande DUMP (D) . Que constatez-vous ? d) Affichage d’un caractère à l’écran Nous allons maintenant afficher à l’écran les mêmes informations en utilisant une routine d’interruption du BIOS. Pour cela nous allons tout d’abord afficher une simple lettre à l’écran pour mettre en œuvre le principe de fonctionnement d’une routine d’ interruption, en l’occurrence l’interrupt 21 Cet routine est capable de réaliser de nombreuses fonctions. Elle lit le contenu du registre AH pour savoir quelle opération elle doit réaliser. Dans notre exemple il faudra mettre la valeur 2 dans le registre AH pour lui signifier qu’elle doit afficher à l’écran le caractère correspondant au code ASCII contenu dans le registre DL. Une fois ces opération réaliser on lancera l’exécution de la routine d’interruption grâce à l’instruction : INT 21 Chargez le registre DL avec le code ASCII du caractère que vous voulez affichez, puis chargez 2 dans AH et lancer l’interrupt 21. Important : quand vous aurez entré ces instructions avec la commande A, n’exécutez pas l’instruction INT avec la trace sinon vous allez tracer toutes les instructions de la routine d’interrupt (et elles peuvent être nombreuses). Utilisez la commande GO (G). Mais attention le programme ne s’arrêtera que si vous rendez le contrôle au DOS, ce qui se fait aussi en utilisant l’interrupt 21, mais cette fois en mettant 4C dans AH et 00 dans AL e) Affichage d’une chaîne de caractères à l’écran Pour indiquer à la routine d’interruption 21 qu’elle doit afficher à l’écran une chaîne de caractère, il faut cette fois mettre la valeur 9 dans AH (au lieu de 2 pour un simple caractère). L’adresse du début de la chaîne de caractères est donnée par : - l’adresse du segment dans lequel elle se trouve. (dans notre cas le contenu du registre CS) que l’on doit charger dans le registre DS (Data Segment). NB : on ne peut charger DS qu’à partir d’un registre. Il faudra donc d’abord charger la valeur de CS par exemple dans AX, puis transférer AX dans DS. - l’offset par rapport à cette adresse que l’on doit charger dans le registre DX La fin de la chaîne de caractère doit être indiquée par la présence d’un caractère $ qui doit obligatoirement finir cette chaîne, sinon la routine d’interruption affiche tous les caractères jusqu’à la fin du segment ou jusqu’à ce qu’elle rencontre un octet contenant le code du caractère . En vous aidant de ces informations, affichez à l’écran le contenu des adresses hexadécimales commençant en 0210. Vous pouvez ensuite afficher votre nom qui se trouve à l’adresse 220, mais n’oubliez pas de lui ajouter un caractère $ à la fin.