Top Banner

of 71

Apprendre l'Assembleur

May 30, 2018

Download

Documents

electroblida
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 8/14/2019 Apprendre l'Assembleur

    1/71

    A S S E M B L E U R

    Apprendre l'assembleur(INTEL - DOS 16 bits)

    Par Benot-M

    Ce document a t tlcharg depuishttp://benoit-m.developpez.com/assembleur/tutoriel

    Dernire modification du contenu le 03 janvier 2003

    Dsormais, pour apprendre le franais, il faudra SAVOIR le franais ! disait Coluche.De mme, ce tutoriel s'adresse tous ceux qui connaissent dj les rudiments dun langagevolu tel que le BASIC, le FORTRAN, le C ou le PASCAL et qui souhaitent apprendrel'assembleur. Une connaissance mme sommaire dun de ces langages suffit ! Aucuneconnaissance en programmation systme nest requise : le but de ce cours est justement denintroduire les fondements.

    Contrairement aux langages volus, l'assembleur, ou langage dassemblage est constitud'instructions directement comprhensibles par le microprocesseur : c'est ce qu'on appelle unlangage de bas niveau. Il est donc intimement li au fonctionnement de la machine. C'estpourquoi il est relativement difficile assimiler, en tout cas beaucoup plus que les langages dehaut niveau.

    Cela explique galement pourquoi il existe au moins autant de langages dassemblage que demodles de microprocesseurs.

    Avant d'apprendre lassembleur INTEL 80x86, il est donc primordial de sintresser quelques

    notions de base concernant par exemple la mmoire ou le microprocesseur. Cest l en effetque se trouvent les principales difficults pour le dbutant. Ne soyez pas rebut par labstractiondes concepts prsents dans les premiers paragraphes : il est normal que durant la lecture,beaucoup de choses ne soient pas claires dans votre esprit. Tout vous semblera beaucoup plussimple quand nous passerons la pratique dans le langage assembleur.

    Le microprocesseur peut fonctionner sous deux modes : le mode relet le mode protg. Lemode protg permet daccder 232 octets de mmoire vive, alors que le mode rel ne peuten adresser que 220 = 1 Mo. Nous ne traiterons dans ce cours que le mode rel. Cest celuiquutilisent la plupart des programmes DOS.

    Convention : toutes les adresses sont crites en notation hexadcimale. Les autres nombresseront la plupart du temps reprsents en base dcimale. Dans le cas contraire, nousajouterons la lettre h aprs les chiffres.

  • 8/14/2019 Apprendre l'Assembleur

    2/71

    PREMIERE PARTIE

    NOTIONS DE BASE SUR LE FONCTIONNEMENT DE L'ORDINATEUR

    I. LARITHMETIQUE SIGNEE

    On appelle arithmtique non signe larithmtique dans laquelle tous les entiers sontpositifs. En arithmtique signe au contraire, les nombres peuvent tre soit positifs, soitngatifs. Un nombre sign nest donc pas forcment ngatif.

    Les donnes informatiques se prsentent sous la forme dune succession de chiffres binaires,les bits. Nous supposerons que les systmes de numration binaire et hexadcimal vous sontdj familiers.

    Il est en revanche fort possible que vous ne connaissiez pas la faon dont un ordinateurreprsente les nombres ngatifs. Il existe deux conventions : la notation en signe et valeurabsolueet la notation en complment 2.

    La premire est extrmement simple : le premier bit reprsente le signe, et les autres bits lavaleur absoluedu nombre. Le bit de signe vaut 1 si le nombre est strictement ngatif, 0 sinon.

    Par exemple, le nombre (14) cod sur 8 bits scrit ainsi :

    10001110

    Cette convention nest quasiment jamais utilise en informatique. On lui prfre lareprsentation en complment 2 dont le principe est le suivant :

    - les nombres positifs sont cods de la mme faon quen convention signe et valeurabsolue.

    - les nombres ngatifs sont obtenus en inversant tous les bits, puis en ajoutant 1.

    Exemple : le nombre 14 cod sur 8 bits est reprsent ainsi :

    00001110

    et (14) ainsi :

    inversion des bits : 11110001

    ajout dune unit : 11110010

    rsultat : 11110010

    Remarque : le rsultat intermdiaire, 11110001, est appel complment 1 .

    Vous allez immdiatement comprendre lavantage de cette reprsentation. Faisons la sommede 14 et de (14), de la mme faon que sil sagissait dentiers positifs :

  • 8/14/2019 Apprendre l'Assembleur

    3/71

    00001110 + 11110010 = 100000000

    Le rsultat tant cod sur 8 bits, le 1 situ gauche nest pas pris en compte. On obtient donc14 + (-14) = 0.

    Lintrt vident est que la diffrence de deux nombres peut se calculer avec le mmealgorithme que leur somme. Il suffit de transformer au pralable le nombre retranch en son

    oppos. Cette conversion est trs simple et trs rapide.

    Au contraire, en reprsentation signe et valeur absolue, on aurait eu besoin de nombreuxalgorithmes, car plusieurs cas se prsentent.

    Remarque : la reprsentation en complment 2 revient en fait crire (-1) comme ceci :

    11111111

    (-2) comme cela :

    11111110

    (-3) comme cela :

    11111101

    etc

    Il y a ainsi une symtrie entre les nombres positifs et les nombres ngatifs. Il en rsulte que lebit le plus gauche reprsente le signe, de la mme faon quen notation signe et valeur

    absolue. Avant tout calcul, nous pouvons donc affirmer que le nombre 10010101 est ngatif.

  • 8/14/2019 Apprendre l'Assembleur

    4/71

    II. LA MEMOIRE VIVE

    1. La segmentation de la mmoire

    Votre PC est conu pour grer 1 Mo (soit 220 octets) de mmoire vive en mode rel. Ilfaut donc 20 bits au minimum pour adresser toute la mmoire. Or en mode rel les bus

    dadresses nont que 16 bits. Ils permettent donc d'adresser 216 = 65536 octets = 64 Ko, ce quiest insuffisant !

    Afin de pallier ce manque, on utilise deux nombres pour adresser un octet quelconque de laRAM. Le premier est appel adresse de segment, le second adresse d'offset. Ils seront stockssparment.

    La mmoire est ainsi dcoupe en segments de 64 Ko chacun. Un segment est donc enquelque sorte un gros bloc de mmoire auquel on peut accder grce une adresse desegmentqui dsigne son numro. Par exemple, le premier segment est le segment 0000 (enhexa), le deuxime est le 0001, le quarante-deuxime est le 0029, etc... Chaque numro estcod sur 16 bits, cest--dire 4 chiffres hexa.

    Pour accder un octet particulier dans un segment, il suffit de compter le dcalagede cetoctet par rapport au dbut du segment. Ce dcalage est obligatoirement infrieur ou gal 65535 : il tient bien sur 16 bits lui aussi. On appelle ce dcalage offset.

    L'adresse d'un octet se note XXXX:YYYY o XXXX est l'adresse de segment et YYYY estl'offset (tous deux en notation hexadcimale, bien sr).

    Par exemple, le dix-septime octet de la RAM (le numro 16) est situ l'adresse 0000:0010.

    De mme, loctet 0000:0100 est l'octet numro 256. Nous en arrivons la petite subtilit quilconvient de bien saisir, sous peine de ne rien comprendre certains programmes enassembleur.

    On pourrait penser que loctet qui se trouve ladresse 0001:0000 est le numro 65536. Il nenest rien. C'est l'octet numro 16.

    Eh oui ! Les segments ne sont pas situs gentiment les uns la suite des autres. Ils sont fortmal levs et n'attendent pas que les segments qui les prcdent soient termins avant decommencer ! Ils se marchent donc sur les pieds.

    Autrement dit, le deuxime segment ne dmarre pas l'octet 65536 comme il devrait le faire s'iltait bien sage, mais l'octet 16 ! Le troisime dmarre l'octet 32 et ainsi de suite

    La notion de segment nest pas tant physique que mathmatique : elle sert se reprer dans laRAM.

    La consquence immdiate de tout cela est qu'un octet n'a pas une adresse unique. Parexemple, l'octet numro 66 peut tre adress par 0000:0042, mais aussi par 0001:0032, par0002:0022, par 0003:0012 ou encore par 0004:0002. Toutes ces adresses sont quivalentes.

    Voil pour la subtilit. Si vous avez compris, vous devriez tre capable de trouver facilementcomment on calcule l'adresse effective d'un octet, c'est dire sa position absolue dans la RAM.

    Allez, un petit effort !

  • 8/14/2019 Apprendre l'Assembleur

    5/71

    Voici la solution : si l'adresse de l'octet est A17C:022E, alors son adresse effective est A17Cx 16 + 022E, soit A17C0 + 022E = A19EE. On a multipli par 16, car le segment A17C dbute loctet A17C x 16, puis on a simplement ajout le dcalage.Au final, on a bien une adresse sur 20 bits puisqu'on obtient 5 chiffres hexa. Chaque petit blocde 16 octets sappelle un paragraphe.

    Remarque importante : Il est souvent plus simple de considrer quun segment est un bloc detaille quelconquequi dbute une adresse effective multiple de 16 et qui permet, laide deson adresse de segmentet dun offset, dadresser le bloc entier (64 Ko au maximum). Cettedfinition est notre avis celle qui a le plus de sens, et nous l'utiliserons tout au long de cecours.

    2. Structure dun programme en mmoire

    Lorsque lutilisateur excute un programme, celui-ci est dabord charg en mmoire parle systme. Le DOS distingue deux modles de programmes excutables : les fichiers COM etles fichiers EXE.

    La diffrence fondamentale est que les programmes COM ne peuvent pas utiliser plus dunsegment dans la mmoire. Leur taille est ainsi limite 64 Ko. Les programmes EXE ne sontquant eux limits que par la mmoire disponible dans lordinateur.

    a) les fichiers COM

    Lorsquil charge un fichier COM, le DOS lui alloue toute la mmoire disponible. Si celle-ciest insuffisante, il le signale lutilisateur par un message et annule toute la procduredexcution. Dans le cas contraire, il cre le PSP du programmeau dbut du bloc de mmoirerserv, et copie le programme charger la suite.

  • 8/14/2019 Apprendre l'Assembleur

    6/71

    Mais quest-ce donc quun PSP ?

    Pour simplifier, le PSP ( Program Segment Prefix) est une zone de 256 (= 100h) octets quicontient des informations diverses au sujet du programme. Cest dans le PSP que se trouve laligne de commande tape par lutilisateur. Par exemple, le PSP dun programme appelMONPROG, excut avec la commande MONPROG monfic.txt /S /H, contiendra la chane decaractres suivante : monfic.txt /S /H. Le programmeur a ainsi la possibilit daccder aux

    paramtres.

    Voici titre indicatif la structure simplifie du PSP (ne vous souciez pas de ce que vous necomprenez pas : pour l'instant, seules les deux dernires lignes nous intressent vraiment) :

    Offset Description Taille (octets)

    00h Appel de l'int 20h 202h Adresse du 1er segment qui se trouve au del du prog. 204h Rserv 105h Far call de l'int 21h (inutilis) 5

    0Ah Vecteur de l'int 22h 40Eh Vecteur de l'int 23h 412h Vecteur de l'int 24h 416h Rserv 222Ch Segment du bloc d'environnement 22Eh Rserv 82

    80hNombre de caractres dans la ligne de commande sanscompter le code ASCII 13 (retour chariot)

    1

    81hLigne de commande ( partir du caractre espace qui suit lenom du programme) + code ASCII 13

    127

    A prsent que nous connaissons lexistence du PSP, il nous faut revenir sur un point important.Comme nous lavons dit, un programme COM ne peut comporter quun seul segment, bien quele DOS lui rserve la totalit de la mmoire disponible. Ceci a deux consquences. La premireest que les adresses de segment sont inutiles dans le programme : les offsets seuls permettentdadresser nimporte quel octet du segment. La seconde est que le PSP fait partie de cesegment, ce qui limite 64 Ko 256 octets la taille maximale dun fichier COM. Cela impliquegalement que le programme lui-mme dbute loffset 100het non loffset 0h.

    b) les fichiers EXE

    Pour un fichier EXE, tout est toujours un peu plus compliqu. (Devise du programmeur dbutant en assembleur)

    Bien quil soit possible de nutiliser quun seul segment tout faire, la plupart desprogrammes EXE ont un segment rserv au code(cest ainsi quon appelle les instructions dulangage machine), un ou deux autres aux donnes, et un dernier la pile.

    La pile est une mmoire trs spciale qui sert comme son nom lindique empilerdes donnesde 16 bits de faon temporaire. On peut ensuite retrouver ces donnes en les dpilant. Le dpilage se fait toujours dans lordre inverse de lempilage.

    Le PSP a lui aussi son propre segment. Le programme commence donc loffset 0h dusegment de code et non loffset 100h.

  • 8/14/2019 Apprendre l'Assembleur

    7/71

    Afin que le programme puisse tre charg et excut correctement, il faut que le systme sacheo commence et o sarrte chacun de ces segments. A cet effet, les compilateurs crent unen-tte (ou header) au dbut de chaque fichier EXE. Ce header ne sera pas copi enmmoire. Son rle est simplement dindiquer au DOS (lors du chargement) la position relativede chaque segment dans le fichier.

    3. Les cycles de lecture-criture

    Le code et les variables dun programme se trouvent dans la mmoire vive. Pour accder une donne en mmoire, le processeur place son adresse dans un bus dadresse. Un cyclede lecturese met alors en place. Il consiste retourner la donne lue au processeur via le busde donnes.

    Pour lcriture, ladresse de la destination est transmise dans le bus dadresse et la donne crire est place dans le bus de donnes.

    Ouf !

    Nous aurons loccasion de revenir sur la mmoire vive dans les autres chapitres pour apporterquelques prcisions. Vous devriez mieux comprendre toutes ces notions en lisant la suite, carjusquici nous navons pas encore parl de la faon dont lordinateur se sert des adresses pouraccder des donnes ou pour excuter du code. Cest l quintervient le microprocesseur...

  • 8/14/2019 Apprendre l'Assembleur

    8/71

    III. LE MICRO-PROCESSEUR LES REGISTRES

    1. Gnralits sur les registres

    Le microprocesseur est le cur de lordinateur. Cest lui qui est charg de reconnatreles instructions et de les excuter (ou de les faire excuter). Chaque instruction se prsente

    sous la forme dune suite de bits quon reprsente en notation hexadcimale (exemple : B44C,ou 1011010001001100 en binaire). Une instruction se compose dun code oprateur (le plussouvent appel opcode) qui dsigne laction effectuer (B4 dans notre exemple) et dun champ doprandes sur lesquelles porte lopration (ici loprande est 4C).

    Pour travailler, le microprocesseur utilise de petites zones o il peut stocker des donnes. Ceszones portent le nom de registreset sont trs rapides d'accs puisqu'elles sont implantes dansle microprocesseur lui-mme et non dans la mmoire vive.

    Les registres des processeurs INTEL se classent en quatre catgories :

    les registresgnraux(16 bits)

    les registresde segment(16 bits)

    les registresd'offset(16 bits)

    le registre desindicateurs(16 bits)

    2. Les registres gnraux

    Ils ne sont pas rservs un usage trs prcis, aussi les utilise-t-on pour manipuler desdonnes diverses. Ce sont en quelque sorte des registres tout faire. Chacun de ces quatreregistres peut servir pour la plupart des oprations, mais ils ont tous une fonction principale quiles caractrise.

    Nom Fonction privilgie

    AX AccumulateurBX BaseCX Compteur

    DX Donnes

    Le registre AX sert souvent de registre d'entre-sortie : on lui donne des paramtres avantd'appeler une fonction ou une procdure. Il est galement utilis pour de nombreusesoprations arithmtiques, telles que la multiplication ou la division de nombres entiers. Il estappel accumulateur.

    Exemples d'utilisation :

    linstruction MOV AX, 1982 place lentier 1982 dans AX.

    ADD AX, 1983 ajoute AX le nombre 1983 et place le rsultat dans AX.

    Le registre BX peut servir de base. Nous verrons plus tard ce que ce terme signifie.

  • 8/14/2019 Apprendre l'Assembleur

    9/71

    Le registre CX est utilis comme compteur dans les boucles. Par exemple, pour rpter 15 foisune instruction en assembleur, on peut mettre la valeur 15 dans CX, crire l'instructionprcde d'une tiquette qui reprsente son adresse en mmoire, puis faire un LOOP cetteadresse. Lorsqu'il reconnat l'instruction LOOP, le processeur sait que le nombre d'itrations excuter se trouve dans CX. Il se contente alors de dcrmenter CX, de vrifier que CX estdiffrent de 0 puis de faire un saut (jump) ltiquette mentionne. Si CX vaut 0, leprocesseur ne fait pas de saut et passe linstruction suivante.

    Exemple :

    Le registre DX contient souvent l'adresse d'un tampon de donnes lorsqu'on appelle unefonction du DOS. Par exemple, pour crire une chane de caractres l'cran, il faut placerloffset de cette chane dans DX avant d'appeler la fonction approprie.

    Chacun de ces quatre registres comporte 16 bits. On peut donc y stocker des nombres allant de0 65535 en arithmtique non signe, et des nombres allant de 32768 32767 enarithmtique signe. Les 8 bits de poids fort dun registre sont appels partie haute et les 8autres partie basse. Chaque registre est en fait constitu de deux sous-registres de 8bits. La partie haute de AX sappelle AH, sa partie basse AL. Il en va de mme pour les troisautres.

    En arithmtique non signe, il en dcoule la formule suivante :

    AX = AH x 256 + AL

    ainsi que leurs homologues :

    BX = BH x 256 + BL

    CX = CH x 256 + CL

    DX = DH x 256 + DL

    Il va de soi quen modifiant AL ou AH, on modifie galement AX.

    Pour stocker un nombre de 32 bits, on peut utiliser des paires de registres. Par exemple, DX:AXsignifie DX x 65535 + AX en arithmtique non signe. Cette notation (DX:AX) nest pasreconnue par lassembleur (ni par la machine). Ne confondez pas cela avec les adresses desegment et doffset.

  • 8/14/2019 Apprendre l'Assembleur

    10/71

    Sur un PC relativement rcent, AX, BX, CX, DX ne sont en fait que les parties basses deregistres de 32 bits nomms EAX, EBX, ECX, EDX ( E pour Extended ). On a donc unmoyen plus pratique de stocker les grands nombres. En fait, chaque registre (pas seulement lesregistres gnraux) peut contenir 32 bits.

    3. Les registres de segment

    Ils sont au nombre de quatre :

    Nom Nom complet Traduction

    CS Code segment Segment de codeDS Data segment Segment de donnesES Extra segment Extra segmentSS Stack segment Segment de pile

    Contrairement aux registres gnraux, ces registres ne peuvent servir pour les oprationscourantes : ils ont un rle trs prcis. On ne peut dailleurs pas les utiliser aussi facilement que

    AX ou BX, et une petite modification de lun deux peut suffire planter le systme. Eh oui !Lassembleur, ce nest pas Turbo Pascal ! Il ny a aucune barrire de protection, si bien quunepetite erreur peut planter le DOS. Mais rassurez-vous : tout se rpare trs bien en redmarrantlordinateur

    Dans le registre CS est stocke ladresse de segment de la prochaine instruction excuter. Laraison pour laquelle il ne faut surtout pas changer sa valeur directement est vidente. De toutefaon, vous ne le pouvez pas. Le seul moyen viable de le faire est dutiliser des instructionstelles que des sauts (JMP) ou des appels (CALL) vers un autre segment. CS sera alorsautomatiquement actualis par le processeur en fonction de ladresse darrive.

    Le registre DS est quant lui destin contenir ladresse du segment des donnes duprogramme en cours. On peut le faire varier condition de savoir exactement pourquoi on lefait. Par exemple, on peut avoir deux segments de donnes dans son programme et vouloiraccder au deuxime. Il faudra alors faire pointer DS vers ce segment.

    ES est un registre qui sert adresser le segment de son choix. On peut le changer aux mmesconditions que DS. Par exemple, si on veut copier des donnes dun segment vers un autre, onpourra faire pointer DS vers le premier et ES vers le second.

    Le registre SS adresse le segment de pile. Il est rare quon doive y toucher car le programme

    na quune seule pile.Intressons-nous prsent aux valeurs que le DOS donne ces registres lors du chargementen mmoire dun fichier excutable ! Elles diffrent selon que le fichier est un programme COMou EXE. Pour crire un programme en assembleur, il est ncessaire de connatre ce tableaupar cur :

    Valeur avant lexcutionRegistre

    Fichier COM Fichier EXE

    CSAdresse de lunique segment, cest

    dire adresse de segment du PSPAdresse du segment de code

    DSAdresse de lunique segment, cest dire adresse de segment du PSP Adresse de segment du PSP

    ES Adresse de lunique segment, cest Adresse de segment du PSP

  • 8/14/2019 Apprendre l'Assembleur

    11/71

    dire adresse de segment du PSP

    SSAdresse de lunique segment, cest dire adresse de segment du PSP Adresse du segment de pile

    Le schma suivant montre mieux la situation :

    Dans un fichier EXE, le headerindique au DOS les adresses initiales de chaque segment parrapport au dbut du programme (puisque le compilateur n'a aucun moyen de connatrel'adresse laquelle le programme sera charg). Lors du chargement, le DOS ajoutera cesvaleurs l'adresse d'implantation pour obtenir ainsi les vritables adresses de segment.Dans le cas d'un fichier COM, tout est plus simple. Le programme ne comporte qu'un seulsegment, donc il suffit tout btement au DOS de charger CS, DS, ES et SS avec l'adressed'implantation.

    Remarque : Pourquoi DS et ES pointent-ils vers le PSP dans le cas dun fichier EXE ?Premireraison : pour que le programmeur puisse accder au PSP ! Deuxime raison : parce quunprogramme EXE peut comporter un nombre quelconque de segments de donnes. Cest doncau programmeur dinitialiser ces registres, sil veut accder ses donnes.

    4. Les registres doffset

    Les voici :

    Nom Nom complet Traduction

    IP Instruction pointer Pointeur dinstructionSP Stack pointer Pointeur de pileSI Source index Index de sourceDI Destination index Index de destination

  • 8/14/2019 Apprendre l'Assembleur

    12/71

    BP Base pointer Pointeur de base

    Le registre IP dsigne loffset de la prochaine instruction excuter, par rapport au segmentadress par CS. La combinaison de ces deux registres (i.e. CS:IP) suffit donc connatreladresse absolue de cette instruction. Le processeur peut alors aller la chercher en mmoire etlexcuter. De plus, il actualise IP en lincrmentant de la taille de linstruction en octets. Toutcomme CS, il est impossible de modifier IP directement.

    Le registre SP dsigne le sommet de la pile. Il faut bien comprendre le fonctionnement de lapile, aussi allons-nous insister sur ce point. La pile ne peut stocker que des mots. On appelle unmot ( word en anglais) un nombre cod sur deux octets (soit 16 bits). Prenons un exemplesimple : un programme COM. Le segment de pile (adress par SS) et le segment de code nefont quun. Avant lexcution, SP vaut FFFE. Cest loffset de la dernire donne de 16 bitsempile, par rapport SS bien sr. Pourquoi FFFE ? Tout simplement parce que la pile seremplit lenvers, cest--dire en partant de la fin du segment et en remontant vers le dbut. Lepremier mot empil se trouve loffset FFFE. Il tient sur deux octets : loctet FFFE et loctetFFFF. Mais comment se fait-il quun mot soit dj empil avant le dbut du programme ? Cemot est un zro que le DOS place sur la pile avant lexcution de tout programme COM. Nousen verrons la raison plus tard.

    A prsent, que se passe-t-il si un instant quelconque une instruction ordonne au processeurdempiler un mot ? Eh bien le stack pointersera dcrmentde 2 et le mot sera copi lendroitpoint par SP. Rappelez-vous que la pile se remplit lenvers ! Cest pour cette raison que SPest dcrment chaque empilage et non pas incrment.

    Un petit exemple pour rendre les choses plus concrtes :

    PUSH AX

    Leffet de cette instruction est dempiler le mot contenu dans le registre AX. Autrement dit, SPest automatiquement dcrment de 2, puis AX est copi ladresse SS:SP.

    Lors du dpilage, le mot situ au sommet de la pile, cest--dire le mot adress par SS:SP, esttransfr dans un registre quelconque choisi par le programmeur, aprs quoi le stack pointerest incrment de 2.

    Exemple :

    POP BX

    Cette fois, on retire le dernier mot empil pour le placer dans le registre BX. Evidemment, SPsera incrment de 2 aussitt aprs.

    La pile est extrmement utile lorsquil sagit de stocker provisoirement le contenu dun registrequi doit tre modifi.

    Exemple :

  • 8/14/2019 Apprendre l'Assembleur

    13/71

    Il est important de comprendre quon ne peut dpiler que le mot qui se trouve au sommet de lapile. Le premier mot empil est le dernier qui sera dpil. La pile doit tre manipule avec uneextrme prcaution. Un dpilage injustifi fait planter la machine presque systmatiquement.

    Les trois derniers registres sont beaucoup moins lis au fonctionnement interne du processeur.Ils sont mis la disposition du programmeur qui peut les modifier sa guise et les utilisercomme des registres gnraux. Comme ces derniers cependant, ils ont une fonction qui leur estpropre : servir dindex(SI et DI) ou de base(BP). Nous allons expliciter ces deux termes.

    Dans la mmoire, les octets se suivent et forment parfois des chanes de caractres. Pourutiliser une chane, le programmeur doit pouvoir accder facilement tous ses octets, lun aprslautre. Or pour effectuer une opration quelconque sur un octet, il faut connatre son adresse.Cette adresse doit en gnral tre une constante valuable par le compilateur. Pourquoi uneconstante ? Parce que ladresse est une oprande comme les autres, elle se trouveimmdiatement aprs lopcode et doit donc avoir une valeur numrique fixe !

    Prenons un exemple :

    MOV AH, [MonOctet]

    Pas de panique ! Cette instruction en assembleur signifie Mettre dans AH la valeur de loctetadress par le label MonOctet !. A la compilation, MonOctet sera remplac par la valeurnumrique qu'il reprsente et on obiendra alors une instruction en langage machine telle que :

    8A260601

    8A26 est lopcode (hexa) de linstruction MOV AH, [constante quelconque], et 0601 est loffsetde MonOctet.

    Il serait pourtant fastidieux, dans le cas dune chane de 112 caractres, de traiter les octetsavec 112 instructions dans lesquelles seule ladresse changerait. Il faudrait pouvoir faire uneboucle sur ladresse, mais alors celle-ci ne serait plus une constante, do le problme.

    Pour les constructeurs du microprocesseur, la seule solution tait de crer de nouveauxopcodes pour chaque opration portant sur un octet en mmoire. Ces opcodes spciauxferaient la mme action que ceux dont ils seraient drivs, mais ladresse passe en paramtreserait alors considre comme un dcalage par rapport un registre spcial. Il suffirait donc defaire varier ce registre, et le processeur y ajouterait automatiquement la valeur de loprandepour obtenir ladresse relle ! Cest cela que servent SI, DI et BP.

    Par exemple :

  • 8/14/2019 Apprendre l'Assembleur

    14/71

    MOV AH, [MonOctet+ DI]

    sera cod :

    8AA50601

    8AA5 est lopcode pour linstruction MOV AH, [constante quelconque+ DI].

    Remarque : les registres SI et BP auraient tout aussi bien pu tre employs, mais pas lesregistres gnraux, SAUF BX. En effet, BX peut jouer exactement le mme rle que BP.Noubliez pas que BX est appel registre de base, et que BP signifie Base Pointer. Nousverrons la diffrence entre une base et un index lorsque nous commencerons lassembleur.

    5. Le registre des indicateurs

    Un programme doit pouvoir faire des choix en fonction des donnes dont il dispose. Pourcela, il lui faut par exemple comparer des nombres, examiner leur signe, dcouvrir si une erreur

    a t constate, etcIl existe cet effet de petits indicateurs, les flags qui sont des bits spciaux ayant unesignification trs prcise. De manire gnrale, les flags fournissent des informations sur lesrsultats des oprations prcdentes.

    Ils sont tous regroups dans un registre : le registre des indicateurs. Comprenez bien quechaque bit a un rle qui lui est propre et que la valeur globale du registre ne signifie rien. Leprogrammeur peut lire chacun de ces flags et parfois modifier leur valeur directement.

    En mode rel, certains flags ne sont pas accessibles. Nous nen parlerons pas. Nous ne

    commenterons que les flags couramment utiliss.

    Nous verrons quelle utilisation on peut faire de ces indicateurs dans la troisime partie de cetutoriel.

    CF ( Carry Flag) est lindicateur de retenue. Il est positionn 1 si et seulement silopration prcdemment effectue a produit une retenue. De nombreuses fonctions duDOS lutilisent comme indicateur derreur : CF passe alors 1 en cas de problme.

    PF ( Parity Flag) renseigne sur la parit du rsultat. Il vaut 1 ssi ce dernier est pair.

    AF ( Auxiliary Carry Flag) est peu utilis.

    ZF ( Zero Flag) passe 1 ssi le rsultat dune opration est gal zro.

    SF ( Sign Flag) passe 1 ssi le rsultat dune opration sur des nombres signs estngatif.

    TF ( Trap Flag) est utilis pour le dbuggage dun programme. Sil vaut 1, uneroutine spciale du dbuggeur est appele aprs lexcution de chaque instruction par leprocesseur.

    IF ( Interrupt Flag) sert empcher les appels dinterruptions lorsquil est positionn 1.Cependant, toutes les interruptions ne sont pas masquables.

  • 8/14/2019 Apprendre l'Assembleur

    15/71

    DF ( Direction Flag) est utilis pour les oprations sur les chanes de caractres. Silvaut 1, celles-ci seront parcourues dans le sens des adresses dcroissantes, sinon lesadresses seront croissantes.

    OF ( Overflow Flag) indique quun dbordement sest produit, cest--dire que lacapacit de stockage a t dpasse. Il est utile en arithmtique signe. Avec desnombres non signs, il faut utiliser ZF et SF.

    Remarque : Les notations CF, PF, AF, etc ne sont pas reconnues par lassembleur. Pourutiliser les flags, il existe des instructions spcifiques que nous dcrirons plus tard.

  • 8/14/2019 Apprendre l'Assembleur

    16/71

    IV. LES INTERRUPTIONS

    1. Introduction

    Le microprocesseur ne peut excuter quune seule instruction la fois. Pour connatreson adresse, il utilise le couple de registres CS:IP dont la valeur est incrmente

    automatiquement. Par consquent, le code du programme courant est excut de manirelinaire.

    Imaginons cependant quun vnement extrieur demande lattention de lordinateur, parexemple la pression dune touche du clavier. La machine doit pouvoir ragir immdiatement,sans attendre que le programme en cours dexcution se termine. Pour cela, elle interrompt cedernier pendant un bref instant, le temps de traiter lvnement survenu puis rend le contrle auprogramme interrompu.

    Une interruption nest rien dautre que lappel dune routine spciale prsente en mmoireappele ISR ( Interrupt Service Routine ).

    Les interruptions se divisent en trois catgories :

    les interruptions lectroniques, par exemple : le clavier

    les interruptions du BIOS, par exemple : laccs aux disques

    les interruptions du DOS, par exemple : laccs aux systmes de fichiers

    Comment sont-elles dclenches ?Une interruption peut tre dclenche par votre matriel. Cest ce qui arrive lorsque vousappuyez sur une touche du clavier. Aucun logiciel nintervient et le contrle est passdirectement la routine qui gre le clavier : ce sont les interruptions matrielles.

    Les interruptions logicielles sont quant elles appeles par des instructions en langagemachine au sein dun programme. Leur importance est capitale. Rappelez-vous quecontrairement au PASCAL ou au C, lassembleur ne dispose pas de fonction prprogramme.Chaque instruction doit tre directement traduisible en langage machine.

    Mais alors, comment fait-on pour crire une chane de caractres lcran ? Ou bien pour lireun caractre entr au clavier ?

    Eh bien on le fait de la mme faon que le DOS lui-mme ! On dclenche les interruptionsappropries laide de linstruction INT du langage machine. Cest donc une routine duDOS (ou parfois du BIOS) qui fera tout le travail. Les paramtres (ou leurs adresses) sontpasss dans les registres.

    Voici un petit exemple en assembleur qui crit la lettre A lcran :

  • 8/14/2019 Apprendre l'Assembleur

    17/71

    Examinons-le ligne par ligne :

    linstruction MOV DL, A demande au processeur de mettre dans le registre DL le codeASCII de la lettre A, cest--dire 65, ou 41h.

    MOV AH, 02: mettre le nombre 2 dans AH.

    Enfin, la dernire instruction appelle linterruption numro 21h. Il existe 256 interruptions.Toutes sont notes en base hexadcimale.

    Explications :

    Comme vous aurez trs vite loccasion de vous en rendre compte, linterruption 21h estlinterruption du DOS par excellence. Elle permet dappeler de nombreuses fonctions trsdiverses. Pour cela, il suffit de mentionner leur numro dans le registre AH.

    Il est trs difficile de mmoriser le rle de chaque interruption, et a fortiori de chaque fonction ousous-fonction, dautant plus delles sont dsignes par des numros hexadcimaux et quellesattendent des paramtres dans des registres prcis. Cest pourquoi tout programmeur se doit

    davoir sa disposition une liste des interruptions pour travailler. Celle de Ralph Brown est trsconnue, et vous la trouverez sur lInternet.

    Revenons notre exemple. La fonction numro 2 de linterruption 21h sert crire un caractre lcran. Il faut pour cela crire le code ASCII du caractre dans le registre DL et bien srplacer le nombre 2 dans AH.

    Une fois que AH et DL ont t ajusts, linterruption 21h peut tre appele laide delinstruction INT.

    Dautres interruptions ne remplissent quune seule tche. Vous navez donc pas besoin de

    mettre un numro de fonction dans AH. Lappel de linterruption suffit.

    2. La table des vecteurs dinterruptions

    A chaque appel dinterruption, lordinateur doit pouvoir trouver ladresse de lISRcorrespondante. Pour cela, il dispose de la table des vecteurs dinterruptions (TVI, ou IVT : Interrupt Vector Table). Cette table est implante ladresse 0000:0000 cest--dire audbut de la RAM.

    La table est organise comme suit :

    Adresse Taille (octets) Valeur

    0000:0000 2 Adresse doffset de linterruption numro 00000:0002 2 Adresse de segment de linterruption numro 0

  • 8/14/2019 Apprendre l'Assembleur

    18/71

    0000:0004 2 Adresse doffset de linterruption numro 10000:0006 2 Adresse de segment de linterruption numro 10000:0008 2 Adresse doffset de linterruption numro 20000:000A 2 Adresse de segment de linterruption numro 20000:000C 2 Adresse doffset de linterruption numro 30000:000E 2 Adresse de segment de linterruption numro 3

    etc

    etc

    etc0000:03FC 2 Adresse doffset de linterruption numro 2550000:03FE 2 Adresse de segment de linterruption numro 255

    La raison pour laquelle les offsets prcdent les adresses de segment vient du codage en little endian utilis par INTEL. Les processeurs de cette marque (contrairement la plupartdes autres, qui travaillent en big endian) ont une reprsentation des donnes en mmoire

    aussi curieuse quinsupportable pour le programmeur : ils placent le poids fort aprs le poidsfaible. Ainsi, le mot 4A28h sera cod 284Ah. Puisque ladresse de lISR tient sur 32 bits (16 +16), elle est reprsente comme un double mot ( dword), donc ladresse doffset, qui est lemot de poids faible, se trouve au dbut. Eh oui, cest pnible, mais il faudra sy faire !

    Remarque : pour calculer ladresse de lentre dans la TVI correspondant linterruptionnumro X, il suffit de multiplier X par 4.

    Exemple : ladresse de lISR numro 21h est stocke 0000:0084.

    3. Sauvegarde de ltat des registres lors de lappel

    Un appel dinterruption obit certaines rgles, car il est indispensable, une fois lISRexcute, que le programme interrompu retrouve les registres dans le mme tat quils taientauparavant. Tout doit se passer comme si linterruption navait jamais eu lieu. Cest pourquoiavant de faire un saut lISR pointe par lentre correspondante dans la TVI, lordinateursauvegarde tous les registres sur la pile courante. Il restaurera leur contenu avant de rendre lecontrle. Cette procdure est automatique. Il nincombe pas au programmeur de prendre toutesces prcautions.

  • 8/14/2019 Apprendre l'Assembleur

    19/71

    DEUXIEME PARTIE

    PREMIER CONTACT AVEC LE LANGAGE ASSEMBLEUR

    Cette partie a pour but de vous prsenter larchitecture du langage assembleur traversde courts exemples. Ne vous inquitez pas si vous ne comprenez pas parfaitement certainesinstructions : toutes seront dtailles dans la troisime partie. Lessentiel est que vouscompreniez grossirement ce quon fait et pourquoi on le fait. Les explications quiaccompagnent ces exemples devraient y suffire. Vous pourrez ensuite apprendre le langage enlui-mme en consultant la partie suivante.

    Remarques pratiques prliminaires :

    Les mots qui sont imprims en italique sont ceux qui ne font pas partie du langage en lui-mme. Ils sont choisis par le programmeur.

    Tous les programmes prsents ci-dessous suivent la syntaxe du compilateur TASM. Ilexiste de trs lgres diffrences dun compilateur lautre.

    Le code peut tre crit en majuscules ou en minuscules. Chaque mot est spar desautres par des espaces ou des tabulations.

    Les commentaires sont prcds du signe ;.

    Les nombres doivent toujours commencer par un chiffre (entre 0 et 9), mme les nombreshexadcimaux. Il faut donc crire 0F2Ah et non pas F2Ah. Par contre, lcriture 5CFh estcorrecte.

    Les apostrophes et les guillemets sont quivalents. Il est cependant plus commode derserver lusage des guillemets aux chanes de plusieurs caractres et celui desapostrophes aux caractres isols.

    Vous pouvez taper vos programmes avec lditeur de texte du DOS (EDIT.COM). Donnez-leur lextension .asm.

    La compilation se fait en tapant TASM /m9 MONPROG si votre source sappelleMONPROG.ASM.

    Le paramtre /m9, facultatif, indique au compilateur quil devra effectuer 9 passes,cest--dire quil examinera 9 fois le code source. Comme chaque examen se fait demanire linaire, le compilateur trouve parfois des instructions qui font rfrence des labels placs plus loin dans le programme. Il manque donc dinformations, mais ilcontinue son examen jusqu la fin. Quand il a termin, il recommence tout depuis ledbut pour rsoudre les problmes qui staient poss.

    La compilation cre un fichier objet (.obj). Pour obtenir un fichier EXE, tapez TLINKMONPROG. Pour un fichier COM, tapez TLINK /tdc MONPROG.

    Aprs ldition des liens (le linkage ), vous pouvez supprimer les fichiers

  • 8/14/2019 Apprendre l'Assembleur

    20/71

    MONPROG.obj et MONPROG.map.

    Il est possible de crer un fichier BAT qui soccupe de toutes ces tapes. Ouvrez lditeurEDIT du DOS et tapez un programme tel que celui-ci :

    @ECHO OFFTASM /m9 %1.asm

    IF NOT EXIST %1.obj GOTO FINTLINK %1.obj REM : ajouter ici /tdc pour obtenir un fichier COMERASE %1.mapERASE %1.obj:FIN

    Enregistrez-le et nommez-le MAKE.BAT. Vous pouvez compiler et linker en tapantMAKE MONPROG. Pour compiler des fichiers COM, ajoutez le paramtre '/tdc' lacommande TLINK.

    Pour pouvoir lancer TASM et TLINK quel que soit le dossier courant, changez la variable

    PATH ainsi :

    PATH = %path%;c:\MonChemin\DossierTASM

    Vous pouvez inclure cette ligne la fin de votre fichier AUTOEXEC.BAT afin quellesoit excute chaque dmarrage.

    Vous pouvez dbugger vos programmes (par exemple les excuter instruction parinstruction en observant les changements induits dans la RAM et dans les registres,...)avec le logiciel Turbo Debugger 16/32 bits qui est trs pratique et trs performant. Adfaut, vous pouvez vous rabattre sur l'archaque DEBUG.COM (il se trouve dans votredossier de commandes DOS). Mais alors bon courage !

    Le seul travail du compilateur (et du linkeur) est de convertir chacune de vos instructionsen son quivalent en langage machine. Le programme compil prsentera donc exactement lamme structure et la mme linarit que votre code source.

  • 8/14/2019 Apprendre l'Assembleur

    21/71

    I. PREMIER EXEMPLE : LES FICHIERS COM

    Voici un petit programme COM qui crit le message Bonjour, monde ! lcran.

    Ce code source commence par des directives. Une directive est une information que leprogrammeur fournit au compilateur. Elle nest pas transforme en une instruction en langagemachine. Elle najoute donc aucun octet au programme compil.

    La directive .386 indique au compilateur que le programme est destin tourner sur desprocesseurs INTEL de modle 386 (ou suprieur). Cela nous autorise utiliser certainesinstructions qui ne sont pas disponibles sur les modles antrieurs, comme PUSHA ou POPA.Dans cet exemple, cette directive aurait trs bien pu tre omise.

    La ligne

    codesegment use16

    sert dclarer un segment que lon appelle code. On aurait tout aussi bien pu le nommermarteau ou voiture. Ce sera le segment de notre programme. Noubliez pas quun fichierCOM ne peut comporter quun seul segment. Cette ligne ne sera pas compile : elle ne sertqu indiquer au compilateur le dbut dun segment.

    Le mot use16 indique que les adresses de segment et doffset sont codes sur 16 bits et nonsur 8 bits. Vous devez systmatiquement lcrire.

    La directiveassume cs:code, ds:code, ss:code

  • 8/14/2019 Apprendre l'Assembleur

    22/71

    informe le compilateur que tout au long du programme, CS, DS et SS pointeront de faonprivilgie vers le segment code, ce qui est vident dailleurs puisque cest le seul segmentVous comprendrez le sens exact de assume dans la troisime partie du cours.

    Enfin, les mots

    org 100h

    signifient quil faudra ajouter 100h (soit 256) tous les offsets. Pourquoi ? Souvenez-vous de lastructure dun programme COM en mmoire. Si vous ncrivez pas cette ligne, TASMconsidrera que le programme dbute loffset 0000. Or, lors de lexcution, le DOS lechargera aprs le PSP, cest--dire ladresse 100h. Cest pourquoi il est ncessaire derecalculer les offsets : loffset 0000 deviendra 0100. Cette directive est en quelque sorte le traitcaractristique des fichiers COM.

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

    debut:

    Lui non plus nest pas compil. Il ne sert qu reprsenter ladresse de linstruction qui le suit,cest--dire :

    mov ah, 09h

    Cette ligne demande au processeur de charger la valeur 9 dans le registre AH. Cest le numrode la fonction de linterruption 21h qui crit une chane de caractres lcran. Loffset de cettechane est attendu dans DX. Do la ligne suivante :

    mov dx, offset messageLe mot-cl offset sert extraire loffset du label message qui reprsente quant lui ladressedu message crire (il contient donc une adresse de segment ET un offset). Ladresse desegment de la chane doit tre transmise dans DS. Mais il est inutile de changer ce registre, caril pointe dj vers notre segment.

    Il nous reste appeler linterruption 21h :

    int 21h

    et rendre la main au DOS :

    ret

    Lorsque nous aborderons les procdures, vous comprendrez mieux le sens de ce mot et cequil fait exactement. Pour linstant, sachez simplement que seul un fichier COM peut seterminer avec cette instruction.

    Nous arrivons la ligne :

    messagedb Bonjour, monde !, $

    Il sagit dune dfinition de donnes. Le mot db ( define byte) signifie que le compilateurdevra crire les octets qui suivent tels quils sont dans notre code source. Il va donc crire lecode ASCII du B, puis celui du o, etc Il terminera en crivant le code ASCII du signe $.

  • 8/14/2019 Apprendre l'Assembleur

    23/71

    Cest ainsi que la fonction 9 de linterruption 21h reconnat la fin de la chane crire. Si vousoubliez ce signe, elle crira tous les octets de la RAM jusqu ce quelle tombe par hasard surlui.

    Le mot message plac en dbut de ligne est un label de donnes. Il reprsente ladresseducode ASCII du B. Remarquez quil ny a pas de caractre : aprs un label de donnes.

    La ligne

    codeends

    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 labeldebut est mentionn : ce sera le point dentre de notre programme. Cest vers lui quepointera CS:IP avant lexcution.

    Remarque : vous ntes pas tenu de rendre aux registres la valeur quils avaient au dbut devotre programme. De toute faon, avant de charger un programme, le DOS sauvegarde lecontenu de tous les registres puis met le contenu des registres gnraux (ainsi que SI, DI etBP) zro. Il les restaurera quand vous lui rendrez la main.

  • 8/14/2019 Apprendre l'Assembleur

    24/71

    II. DEUXIEME EXEMPLE : LES FICHIERS EXE

    Le programme suivant est un programme EXE qui fait exactement la mme chose quelexemple prcdent.

    Examinons-le !

    Tout dabord, la directive

    org 100h

  • 8/14/2019 Apprendre l'Assembleur

    25/71

    a disparu.

    En effet, lors de lexcution, CS pointera vers notre segment de code et non pas vers le PSP. Ilest donc inutile de dcaler les offsets de 256.

    Remarquons que notre programme dispose de deux segments supplmentaires :

    Le segment data est destin contenir les donnes, cest--dire les variables.

    Le segment pile sera notre segment de pile.

    Notre directive assume devient donc :

    assume cs:code, ds:data, ss:pile

    Ainsi, le compilateur est inform que DS pointera vers le segment data et SS vers pile.

    Les deux lignes suivantes,

    mov ax, datamov ds, ax

    servent initialiser le registre DS. Celui-ci pointe vers le PSP au dbut du programme maisnous voulons le faire pointer vers notre segment de donnes appel data. Cela est ncessairepuisque la fonction 9 de linterruption 21h attend ladresse de la chane dans le couple DS:DX etque notre message se trouve dans le segment de donnes.

    La premire instruction charge ladresse du segment data dans AX. La seconde transfre

    cette valeur de AX dans DS.Mais pourquoi diable utiliser AX comme intermdiaire ? Aprs tout, on pourrait crire :

    mov ds, data

    Eh bien non ! Pour la simple raison que DS est un registre de segment et quen tant que tel onne peut pas lui charger de valeur immdiate.

    On appelle valeur immdiate toute constante tape directement dans linstruction elle-mme.

    Exemples de chargement de valeurs immdiates :

    mov ax, 135;charge 135 dans AX

    mov bx, offset message;charge loffset de message dans BX

    mov bx, offset fin offset debut;charge le nombre doctets entre fin et debut dans BX

    mov es, 10;instruction illicite car ES est un registre de segment !

    Remarque : une autre possibilit aurait t d'crire : PUSH AX (empiler AX) puis POP DS(dpiler le dernier nombre empil et le placer dans DS).

    Les trois lignes suivantes :

  • 8/14/2019 Apprendre l'Assembleur

    26/71

    mov ah, 09hmov dx, offset messageint 21h

    nont pas chang.

    Il nous faut galement terminer le programme par un appel de la fonction 4ch de linterruption

    21h. Cest ainsi que se terminent les programmes EXE.

    mov ah, 4chint 21h

    Remarque : on aurait galement pu crire :

    mov ax, 4c00hint 21h

    La seule diffrence est que AL est mis zro, ce qui indique au programme qui on rend le

    contrle (ici le DOS) que notre programme sest termin normalement. Les fichiers COMpeuvent galement utiliser la fonction 4ch.

    Le segment de code se termine :

    codeends

    et le segment de donnes commence sa suite :

    datasegment use16

    messagedb Bonjour, monde !, $

    dataends

    Il nous reste crire le segment de pile. Dans ce programme, il ntait pas absolumentindispensable de le sparer du segment de code. Mais cest une bonne habitude de le faire.

    pilesegment stack

    remplissagedb 256DUP (?)

    pileends

    Le mot-cl stack indique que ce segment est le segment de pile.

    Les mots db 256DUP (?) dclarent 256 octets non initialiss. Cest la matire de notrepile.

    Sachez que tout appel dinterruption se traduit par lempilage des flags et de CS:IP. Il est doncindispensable davoir une pile, mme si celle-ci peut ventuellement partager le mme segmentque le code, comme dans un fichier COM. Mais dans un programme EXE, il vaut mieux

    rserver un segment la pile. Les 256 octets que nous dclarons ici indiquent seulement que lapile contient 256 octets. Ainsi, au dbut de lexcution, SS:SP pointera vers la fin de ces octets.Nous verrons ce que signifie le point dinterrogation dans la troisime partie.

  • 8/14/2019 Apprendre l'Assembleur

    27/71

    La fin du fichier et le point dentre sont signals par :

    end debut

    Et voil ! Vous avez dcouvert lallure dun programme en assembleur. Nous pouvonsdonc prsent nous pencher sur ltude du langage.

  • 8/14/2019 Apprendre l'Assembleur

    28/71

    TROISIEME PARTIE

    LE LANGAGE ASSEMBLEUR

    I. DEFINITION DE DONNEES ET ADRESSAGE

    1. Les dfinitions de donnes

    Les mots db ( define byte), dw ( define word), dd ( define double word)permettent de dclarer et dinitialiser une variable. Il faut bien comprendre que leur seule actionest dcrire les donnes dans lexcutable lendroit mme o elle se trouvent dans le codesource.

    Pour accder ces donnes (appeles variables), il suffit de connatre leur adresse. Pourcela, on peut les faire prcder dun label de donnes.

    Exemple :

    TOTO dw 1982

    Dans la ligne prcdente, TOTO reprsente ladresse du nombre 1982 qui est dfini justeaprs. Comme ce nombre est cod sur deux octets (word = 16 bits), cest le premier octet quiest adress par TOTO.

    Le compilateur se contentera dcrire le nombre 1982 lendroit o se trouve la dclaration.Remarque : en C, on crirait ceci :

    int TOTO = 1982;

    En BASIC ou en PASCAL, cette dfinition na pas dquivalent, puisque les variables nepeuvent tre initialises lors de leur dclaration. Il est donc obligatoire dajouter une ligne decode pour le faire.

    Dans la partie prcdente, nous avons eu dfinir le message qui serait affich lcran. Voici

    la ligne que nous avons crite :

    messagedb Bonjour, monde !, $

    Lorsquil rencontre une chane de caractres, le compilateur crit les codes ASCIIde tous lescaractres, les uns la suite des autres.

    Voici une autre manire dcrire cette dfinition de donnes. Le rsultat (i.e. le programmecompil) est EXACTEMENT LE MME :

    messagedb 42h, 111, nj

    db our, mo

    db nde !$

  • 8/14/2019 Apprendre l'Assembleur

    29/71

    Pour dfinir plusieurs fois la suite les mmes donnes, on utilise DUP ( duplicate)de la manire suivante :

    TOTOdb 100dup(TOTO EST BEAU)

    Cela revient crire :

    TOTOdb TOTO EST BEAU

    TOTOdb TOTO EST BEAU

    TOTOdb TOTO EST BEAU

    ; etc (100 fois)

    Il est frquent que de nombreuses donnes naient pas besoin dtre initialises une valeurprcise. Dans ce cas, on les regroupe la fin du programme et on les remplace par le caractre?. Les adresses des labels seront calcules de la mme faon mais aucune donnes ne sera

    crite dans le fichier (et a fortiori dans la RAM). On dit que lon met ses variables sur le tas( heap en anglais). La seule diffrence avec une dfinition classique est quau dbut delexcution, nos variables nauront pas de valeur dfinie. Leurs valeurs seront alatoires ence sens quon ne peut les connatre au moment de la compilation.

    Exemple :

    Remarque : Si elles ne sont pas regroupes en fin de programme, le compilateur sera obligd'crire les donnes dans le fichier afin de ne pas fausser les adresses des variables (ou du

    code) qui suivent. Il remplira alors les points dinterrogation avec des zros.

    Pour indiquer quun chiffre est not en base hexadcimale, on lui ajoute la lettre h. La lettre bsignifie que le chiffre est cod en binaire, la lettre 'o' en octal et la lettre d en base dcimale(base par dfaut).

    2. Ladressage

    a) ladressage immdiat

    On appelle adressage immdiat ladressage qui ne fait intervenir que des constantes.

    Considrons cette partie de programme qui stocke le nombre 125h dans une variable appeleTOTO, lui ajoute 15 puis charge le rsultat dans AX :

  • 8/14/2019 Apprendre l'Assembleur

    30/71

    La ligne

    mov word ptr ds:[TOTO], 125h

    charge le nombre 125h dans le mot de la RAM adress par DS et loffset de TOTO. La lignesuivante ajoute 15 au contenu de ce mot.

    Lexpression word ptr devant ladresse, obligatoire ici, indique la taille de la variable danslaquelle doit tre stock le nombre 125h.

    Si on avait mis dword ptr, ce nombre aurait t cod sur 32 bits (00000125h) au lieu de 16 bits(0125h) : on aurait donc cras les deux octets qui suivent la variable. Si on avait mis byte ptr,la compilation aurait t impossible car un octet ne peut contenir un nombre suprieur FFh.

    Le compilateur na en effet aucun moyen de connatre cette taille. La variable TOTO na pasde taille (malgr le mot dw) : ce nest en fait quun pointeur vers le premier octet du wordquelle reprsente.

    En revanche, la troisime instruction ne fait pas apparatre lexpression word ptr. Cette fois-cielle est facultative du fait que la destination (AX = 16 bits) impose la taille.

    On peut videmment remplacer TOTO par une constante numrique :

    mov word ptr ds:[004Ch], 125h

  • 8/14/2019 Apprendre l'Assembleur

    31/71

    Le mot 125h sera alors crit ladresse DS:4C.

    Une question se pose prsent : que se passe-t-il si le programmeur ncrit pas le registre desegment dans ladresse ?

    Cest l quintervient la directive assume. Le compilateur va devoir trouver lui-mme quelregistre lutilisateur a voulu sous-entendre.

    Si on a utilis un label, alors le segment sera celui dans lequel est dclar le label. Mais lecompilateur veut un REGISTRE de segment. Il va donc prendre celui qui est cens pointer versle bon segment et pour le savoir, il examine la directive assume.

    Voil pourquoi cette dernire peut nous pargner dcrire pour chaque variable lexpressionds:.

    Comprenez bien que cette directive ne sert rien dautre qu cela et quen aucune faon ellene force les registres de segment prendre quelque valeur que ce soit.

    b) ladressage index et/ou bas

    Comme nous lavons dj expliqu, il est possible dutiliser des registres de base oudindexpour adresser un octet.

    On appelle base les registres BX et BP et index les registres SI et DI. La diffrence estque la base est cense tre fixe tandis que lindex varie automatiquement lorsquon utilisecertaines oprations, telles que MOVSB.

    Remarque : BX, BP, DI et SI peuvent tous tre utiliss comme des registres gnraux.

    Voici les adressages possibles:

    Constante seule (= adressage immdiat) :

    Exemples :

    MOV AH, byte ptr [TOTO]

    MOV BX, word ptr ds:[1045h]

    MOV ES:[10+ TOTOx 2], BL

    Base seule :

    Exemple :

    MOV dword ptr ds:[BP], 15

    Index seul :

    Exemple :MOV dword ptr es:[DI], 142

  • 8/14/2019 Apprendre l'Assembleur

    32/71

    Base + Constante :

    Exemples :

    MOV byte ptr ds:[BP + 1], 12

    MOV ds:[BX + (TOTO BOBO)/10], AX

    Index + Constante :

    Exemples :

    MOV CX, [TOTO+ DI]

    MOV AL, ds:[1 + SI]

    Base + Index :

    Exemple :

    MOV ds:[BP + SI], AH

    Base + Index + Constante :

    Exemple :

    MOV AX, word ptr [TOTO+ BX + DI + 1]

    Remarque : si la constante nest pas un label, il est parfois impratif de spcifier le registre desegment ! Tout dpend du contexte

  • 8/14/2019 Apprendre l'Assembleur

    33/71

    II. SAUTS INCONDITIONNELS, PROCEDURES ET MACROS

    1. Les sauts inconditionnels

    Ce paragraphe rpond la question : Mais comment fait-on un GOTO enassembleur? .

    Linstruction quivalente est JMP qui signifie jump.

    La syntaxe est

    JMP MonLabel

    La rfrence ltiquette MonLabel sera remplace lors de la compilation par la distance(signe) en octets qui spare linstruction qui suit immdiatement le JMP de linstructionadresse par MonLabel. En pratique, le JMP sutilise exactement comme un GOTO en BASIC.

    Cette instruction permet de faire un saut inconditionnel : le programme fera ce saut quoiquilarrive.

    Exemple :

    Le mot short ajout aprs jmp indique au compilateur que le label COUCOU se trouve une distance (signe) qui peut tre stocke sur un seul octet. Le compilateur ne le sait pasencore lorsquil essaie de compiler linstruction de saut car le label se trouve en de de cetteinstruction. Cest pourquoi il prvoit deux octets pour crire le saut, au cas o ladresse darrivesoit loigne de plus de 128 octets. Lorsquil effectue une deuxime passe , sil saperoitquun seul octet aurait suffi il remplit alors loctet inutile avec linstruction NOP ( NoOperation) qui ne fait rien du tout. Le programme marchera parfaitement (encore heureux !),mais cela gaspille un octet. Le programmeur a la possibilit daider le compilateur en ajoutant lemot short, ainsi un seul octet est prvu pour la distance de saut. Si le label est plac plus haut

    que l'instruction de saut, il est inutile de l'crire.Remarque : Ce mot peut galement tre utilis avec les instructions de saut conditionnel quenous tudierons plus loin.

  • 8/14/2019 Apprendre l'Assembleur

    34/71

    2. Les procdures

    a) appels de procdures

    Ceux qui ont dj programm en BASIC connaissent les instructions GOSUB etRETURN. Leurs quivalents en assembleur sont CALL et RET.

    Linstruction CALL sert appeler une procdure :

    Syntaxe

    CALL MonLabel

    Action : empile loffset de linstruction suivante puis fait un simple saut ladresse reprsentepar MonLabel.

    RET (ou RETN) permet de retourner linstruction qui suit immdiatement le CALL :

    Syntaxe :

    RET

    Action : dpile ladresse de retour et la met dans IP. Le programme continue donc ladressequi suit le CALL.

    Remarque : Rappelez-vous quil est possible de terminer un programme COM avec linstructionRET. Puisque le DOS empile un zro de deux octets au chargement du programme, IP prendrala valeur 0000 lorsque le processeur excutera cette instruction : il pointera donc vers le dbutdu PSP. Or le PSP commence toujours par les deux octets suivants : CDh 20h (ce qui scritINT 20h en assembleur). Linterruption 20h, qui permet de terminer un programme COM, seradonc appele et le contrle sera rendu au DOS.

    Voici un exemple dutilisation des procdures aussi simple que possible : ce programme COMappelle 12 fois une procdure qui crit un message lcran et rend la main au DOS. Il nestdaucune utilit et nest pas optimis du tout.

  • 8/14/2019 Apprendre l'Assembleur

    35/71

    Remarque : Les codes ASCII 10 et 13 reprsentent respectivement la fin de ligne et le retourchariot. Grce eux, on revient la ligne chaque fois quon a crit le message.

    Ce programme fonctionne parfaitement. Toutefois, les conventions dcriture veulent que les

    procdures soient crites comme suit :

    Le programme compil est toujours le mme, mais le code est plus lisible puisqu'on distingue

  • 8/14/2019 Apprendre l'Assembleur

    36/71

    les procdures des simples labels. Le mot near signifie que ladresse de cette procdure estrduite un offset. Il ny a pas dadresse de segment. La procdure ne pourra donc treappele que de lintrieur mme du segment.

    Le mot qui a le sens contraire de near est far. Les call far sont assez peu utiliss.

    b) le passage des paramtres

    Il existe deux moyens de passer des paramtres une procdure : les registres et la pile.

    Le passage par registres:

    Il consiste transmettre les paramtres dans des registres convenus lavance, parexemple AX et BX. Les deux gros avantages de cette mthode sont sa simplicit et la vitessedexcution. Linconvnient majeur est le nombre limit de registres, dautant plus quaumoment de lappel, certains dentre eux ne seront peut-tre pas disponibles.

    Le passage par la pile:Cest la mthode quutilisent les langages de haut niveau tels que le C ou le PASCAL. Avant

    lappel, on empile les paramtres un un. La procdure appele se chargera de les lire.

    Pour cela on utilise le registre BP de la manire suivante : on transfre la valeur de SP dans BP laide de linstruction MOV BP, SP. Ladresse de retour (qui sera dpile quand leprocesseur rencontrera l'instruction RET) se trouve ladresse SS:[BP], le dernier paramtreest adress par SS:[BP + 2], lavant-dernier par SS:[BP + 4], etc On peut ainsi lire nimportequel paramtre sans le dpiler.

    Attention cependant ! A la fin de la procdure, il faudra tout de mme rendre SP la valeur quilavait avant lempilage des paramtres. Pour cela, on fait suivre linstruction RET du nombre deparamtres, multipli par 2(car chaque paramtre comporte deux octets).

    Exemple :

  • 8/14/2019 Apprendre l'Assembleur

    37/71

    Soyez toujours trs vigilant avec les appels de procdures : pensez que ladresse de retoursera dpile lorsque le programme rencontrera linstruction RET. Il serait donc suicidaire delaisser une donne empile avant dappeler cette instruction.

    3. Les macros

    Etant donn que certaines instructions se rptent constamment dans un programme,lcriture de macrofonctions (ou macros) est un moyen pratique de rendre votre code sourceplus lisible.

    Il est possible de choisir pour certaines suites dinstructions un nom qui les reprsente. Lorsquele compilateur (en fait, le prprocesseur) rencontrera ce nom dans votre code source, il leremplacera par les lignes de code quil dsigne. Ces lignes forment une macro.

    Les macros, la diffrence des procdures, nont aucune signification pour la machine. Seul lecompilateur comprend leur signification. Elles ne sont quun artifice mis la disposition duprogrammeur pour clarifier son programme. Lorsque le compilateur rencontre le nom dune

    macro dans votre code, il le remplace par le code de la macro. Tout se passe exactementcomme si vous aviez tap vous-mme ce code la place du nom de la macro.

    Ainsi, si vous appelez quinze fois une macro dans votre programme, le compilateur criraquinze fois le code de cette macro. Cest toute la diffrence avec les procdures qui ne sontcrites quune seule fois mais peuvent tre appeles aussi souvent quon veut laide dunCALL.

    Voici comment crire une macro : lexemple suivant sert crire un message lcran.

  • 8/14/2019 Apprendre l'Assembleur

    38/71

    Le code prcdent peut tre crit nimporte o dans votre programme, condition quil setrouve avant tout appel de cette macro. Afin dviter les ennuis, il est fortement conseill derunir vos macros au dbut du code, avant toute autre ligne. De toute faon, il ne sera pascompil lendroit o vous lavez crit mais aux endroits o se trouvent les appels de macros.

    Le mot text? est un paramtre. Le point dinterrogation nest pas requis ; nous lavons mispour indiquer quil sagit dun paramtre et non dune variable. Une macro peut utiliser plusieurs

    paramtres spars par des virgules.

    Pour appeler cette macro, il vous suffit dcrire la ligne

    ecrit_texte Coucou ! Ceci est un essai !

    Le compilateur se chargera alors de la remplacer par les instructions comprises entre lapremire et la dernire ligne de cet exemple, en prenant le soin de remplacer le mot text? parle message fourni en paramtre.

    En assembleur, chaque label doit avoir un nom unique. Or, si une macro est appele plusieursfois, les mmes noms seront utiliss. Il faut donc la plupart du temps inclure la directive LOCALqui forcera le compilateur changer le nom des labels chaque appel de la macro. Attention :cette directive doit suivre immdiatement la dclaration de la macro.

    Supposons prsent que lon veuille crire lcran le message Je suis bien content etrevenir la ligne laide de notre macro ecrit_texte.

    La syntaxe suivante :

    ecrit_texte Coucou ! Ceci est un essai !, 10, 13

    est incorrecte, car le compilateur croirait que lon a crit trois paramtres ! Il faut alors entourernotre unique paramtre par les signes :

  • 8/14/2019 Apprendre l'Assembleur

    39/71

    ecrit_texte

    4. La directive EQU

    La directive EQU a un rle voisin de celui des macros. Elle permet de remplacer unsimple mot par dautres plus complexes. Son intrt est quelle peut tre invoque en pleinmilieu dune ligne.

    Quelques exemples :

    LongueurEQU (fin debut)

    MessageEQU Bonjour messieurs ! Comment allez-vous ?, $

    VersionEQU 2

    QuitterEQU ret

    Quitter2EQU int 20h

    Mettre_dans_AHEQU mov ah,

    Interruption_21hEQU int 21h

    Un programme qui contient de telles directives peut se terminer ainsi :

    Mettre_dans_AH4Ch

    Interruption_21h

    Ou ainsi (si cest un COM) :

    Quitter2

    5. Linclusion de fichiers

    Il est possible daccder des procdures, des macros ou des dfinitions EQU qui setrouvent dans dautres fichiers. Cela permet de se constituer des librairies de macros ou de

    procdures que lon peut rutiliser dun programme lautre.

    Pour inclure le fichier TOTO.LIB, crivez au dbut de votre code source :

    La condition if1 indique au compilateur que linclusion ne doit seffectuer que lors de lapremire passe.

    Le fichier TOTO.LIB est un fichier texte tout fait banal qui contient des lignes de code enassembleur.

  • 8/14/2019 Apprendre l'Assembleur

    40/71

    III. LES PRINCIPALES INSTRUCTIONS DU LANGAGE

    MACHINE

    Remarques prliminaires :

    Le principe du langage assembleur est de remplacer chaque opcode hexadcimal par un

    mot facile retenir. Ce mot est appel mnmonique. Par exemple, INT est lemnmonique associ lopcode CDh. Chaque fois que le compilateur rencontrera cemot, il le remplacera par loctet CDh et crira ensuite loprande (ici : le numro delinterruption) en hexadcimal.

    Cette liste rcapitule les instructions que nous connaissons dj et en prsente denouvelles. Elle nest pas exhaustive mais vous sera amplement suffisante pour la plupartde vos programmes.

    Certaines instructions, comme PUSHA, ne sont disponibles que pour des modles deprocesseurs plus volus que le 8086, par exemple le 286. Noubliez pas la directive

    .386 si vous les utilisez.

    1. Linstruction NOP ( No Operation)

    Syntaxe : NOP

    Description : Ne fait rien ! Mais alors RIEN ! Que dalle ! Niet !

    2. Linstruction MOV ( Move)

    Syntaxe : MOV Destination, Source

    Description : Copie le contenu de Sourcedans Destination.

    Mouvements autoriss : MOV Registre gnral, Registre quelconque

    MOV Mmoire, Registre quelconque

    MOV Registre gnral, Mmoire

    MOV Registre gnral, Constante

    MOV Mmoire, Constante

    MOV Registre de segment, Registre gnral

    Remarques : Sourceet Destinationdoivent avoir la mme taille. On ne peut charger dans unregistre de segment que le contenu dun registre gnral (SI, DI et BP sont considrs icicomme des registres gnraux).

    Exemples : MOV AX, 5

    MOV ES, DX

    MOV AL, [Variable1] ;Copie un octet car AL contient 8 bits

  • 8/14/2019 Apprendre l'Assembleur

    41/71

    MOV [Variable2], DS ;Copie un word car DS contient 16 bits

    MOV word ptr [Variable3], 12;Ici, on spcifie que la variable est un word

    3. Linstruction XCHG ( Exchange)

    Syntaxe : XCHG Destination, Source

    Description : Echange les contenus de Sourceet de Destination.

    Mouvements autoriss : XCHG Registre gnral, Registre gnral

    XCHG Registre gnral, Mmoire

    XCHG Mmoire, Registre gnral

    4. Linstruction JMP ( Jump)

    Syntaxe : JMP MonLabel

    Description : Saute linstruction pointe par MonLabel.

    5. Loprateur CMP ( Compare)

    Syntaxe : CMP Destination, Source

    Description : Cet oprateur sert comparer deux nombres : Source et Destination. C'est leregistre des indicateurs qui contient les rsultats de la comparaison. Ni Sourceni Destinationnesont modifis.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    Remarque : Cet oprateur effectue en fait une soustraction mais contrairement SUB, lersultat nest pas sauvegard.

    Le programme doit pouvoir ragir en fonction des rsultats de la comparaison. Pour cela, onutilise les sauts conditionnels(voir ci-dessous).

    6. Les instructions de saut conditionnel

    Les sauts conditionnels sont terriblement importants car ils permettent au programme defaire des choix en fonction des donnes.

    Un saut conditionnel nest effectu qu certaines conditions portant sur les flags (par exemple :CF = 1 ou ZF = 0).

    Certains mnmoniques de sauts conditionnels sont totalement quivalents, cest--dire quilsreprsentent le mme opcode hexadcimal. Cest pour aider le programmeur quils existentparfois sous plusieurs formes.

    a) les sauts de comparaison

  • 8/14/2019 Apprendre l'Assembleur

    42/71

    JE ( Jump if Equal) fait un saut au label spcifi si et seulement si ZF = 1. Rappelez-vous que ce flag est 1 si et seulement si le rsultat de lopration prcdente vaut zro.Comme CMP ralise une soustraction, on utilise gnralement JE pour savoir si deuxnombres sont gaux.

    Exemple :

    Mnmonique quivalent : JZ ( Jump if Zero)

    JG ( Jump if Greater) fait un saut au label spcifi si et seulement si ZF = 0 et SF= OF. On lutilise en arithmtique signepour savoir si un nombre est suprieur unautre.

    Exemple :

    Mnmonique quivalent : JNLE ( Jump if Not Less Or Equal)

    JGE ( Jump if Greater or Equal) fait un saut au label spcifi si et seulement si SF= OF. On lutilise en arithmtique signepour savoir si un nombre est suprieur ou gal un autre.

    Mnmonique quivalent : JNL ( Jump if Not Less)

    JL ( Jump if Less) fait un saut au label spcifi si et seulement si SF OF. On lutiliseen arithmtique signepour savoir si un nombre est infrieur un autre.

  • 8/14/2019 Apprendre l'Assembleur

    43/71

    Mnmonique quivalent : JNGE ( Jump if Not Greater Or Equal)

    JLE ( Jump if Less Or Equal) fait un saut au label spcifi si et seulement si SF OFou ZF = 1. On lutilise en arithmtique signepour savoir si un nombre est infrieur ougal un autre.

    Mnmonique quivalent : JNG ( Jump if Not Greater)

    JA ( Jump if Above) fait un saut au label spcifi si et seulement si ZF = 0 et CF = 0.On lutilise en arithmtique non signepour savoir si un nombre est suprieur un autre.

    Mnmonique quivalent : JNBE ( Jump if Not Below Or Equal)

    JAE ( Jump if Above or Equal) fait un saut au label spcifi si et seulement si CF = 0.On lutilise en arithmtique non signepour savoir si un nombre est suprieur ou gal un autre.

    Mnmonique quivalent : JNB ( Jump if Not Below)

    JB ( Jump if Below) fait un saut au label spcifi si et seulement si CF = 1. On lutiliseen arithmtique non signepour savoir si un nombre est infrieur un autre.

    Mnmonique quivalent : JNAE ( Jump if Not Above Or Equal)

    JBE ( Jump if Below or Equal) fait un saut au label spcifi si et seulement si CF = 1ou ZF = 1. On lutilise en arithmtique non signepour savoir si un nombre est infrieurou gal un autre.

    Mnmonique quivalent : JNA ( Jump if Not Above)

    b) les sauts de test sur les flags

    Ces instructions testent un flag unique et excutent ou non le saut selon la valeur de ceflag.

    JC ( Jump if Carry) fait un saut au label spcifi si et seulement si CF = 1.

    Remarques : Ce mnmonique correspond au mme opcode que JB. Il est souvent employpour vrifier que lappel dune interruption na pas dclench derreur.

    Exemple :

  • 8/14/2019 Apprendre l'Assembleur

    44/71

    Si lappel de la fonction 3Eh de linterruption 21H se solde par une erreur, alors la CF vaudra 1

    et le saut sera accompli. Dans le cas oppos, lexcution continuera normalement de manirelinaire.

    JNC ( Jump if not Carry) fait un saut au label spcifi si et seulement si CF = 0.

    JZ ( Jump if Zero) fait un saut au label spcifi si et seulement si ZF = 1. Cemnmonique correspond au mme opcode que JE.

    JNZ ( Jump if not Zero) fait un saut au label spcifi si et seulement si ZF = 0. Cemnmonique correspond au mme opcode que JNE.

    JS ( Jump if Sign) fait un saut au label spcifi si et seulement si SF = 1.

    JNS ( Jump if not Sign) fait un saut au label spcifi si et seulement si SF = 0.

    JO ( Jump if Overflow) fait un saut au label spcifi si et seulement si OF = 1.

    JNO ( Jump if not Overflow) fait un saut au label spcifi si et seulement si OF = 0.

    JP ( Jump if Parity) fait un saut au label spcifi si et seulement si PF = 1.

    JNP ( Jump if not Parity) fait un saut au label spcifi si et seulement si PF = 0.

    c) le saut de test sur le registre CX

    JCXZ ( Jump if CX = Zero) fait un saut au label spcifi si et seulement si CX = 0.

    7. Les instructions arithmtiques

    a) linstruction INC ( Increment)

    Syntaxe : INC Destination

    Description : Incrmente Destination.

  • 8/14/2019 Apprendre l'Assembleur

    45/71

    Indicateurs affects : AF, OF, PF, SF, ZF

    Exemple : INC CL

    b) linstruction ADD ( Addition)

    Syntaxe : ADD Destination, Source

    Description : Ajoute Source Destination

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    Exemple : ADD byte ptr [VARIABLE+ DI], 5

    c) linstruction ADC ( Add with Carry)

    Syntaxe : ADC Destination, Source

    Description : Ajoute (Source+ CF) Destination.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    d) linstruction DEC ( Decrement)

    Syntaxe : DEC Destination

    Description : Dcrmente Destination.

    Indicateurs affects : AF, OF, PF, SF, ZF

    e) linstruction SUB ( Substract)

    Syntaxe : SUB Destination, Source

    Description : Soustrait Source Destination.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    f) linstruction SBB ( Substract with Borrow)

    Syntaxe : SBB Destination, Source

    Description : Soustrait (Source+ CF) Destination.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    g) linstruction MUL ( Multiply)

    Syntaxe : MUL Source

    Description : Effectue une multiplication dentiers non signs.

  • 8/14/2019 Apprendre l'Assembleur

    46/71

    Si Sourceest un octet : AL est multipli par Sourceet le rsultat est plac dans AX.

    Si Sourceest un mot : AX est multipli par Sourceet le rsultat est plac dans DX:AX.

    Si Sourceest un double mot : EAX est multipli par Sourceet le rsultat est plac dansEDX:EAX.

    Indicateurs affects : CF, OF

    Remarque : Source ne peut tre une valeur immdiate.

    Exemples : MUL CX

    MUL byte ptr [TOTO]

    h) linstruction IMUL ( Integer Multiply)

    Syntaxe : IMUL SourceIMUL Destination, Source

    IMUL Destination, Source, Valeur

    Description : Effectue une multiplication dentiers signs.

    IMUL Source:

    Si Sourceest un octet : AL est multipli par Sourceet le rsultat est plac dans AX.

    Si Sourceest un mot : AX est multipli par Sourceet le rsultat est plac dans DX:AX.

    Si Sourceest un double mot : EAX est multipli par Sourceet le rsultat est plac dansEDX:EAX.

    IMUL Destination, Source: Multiplie Destination par Source et place le rsultat dansDestination.

    IMUL Destination, Source, Valeur: Multiplie Source par Valeur et place le rsultat dansDestination.

    Indicateurs affects : CF, OF

    i) linstruction DIV ( Divide)

    Syntaxe : DIV Source

    Description : Effectue une division euclidienne dentiers non signs.

    Si Sourceest un octet : AX est divis par Source, le quotient est plac dans AL et le reste

    dans AH.

    Si Sourceest un mot : DX:AX est divis par Source, le quotient est plac dans AX et lereste dans DX.

  • 8/14/2019 Apprendre l'Assembleur

    47/71

    Si Sourceest un double mot : EDX:EAX est divis par Source, le quotient est plac dansEAX et le reste dans EDX.

    Indicateurs affects : AF, OF, PF, SF, ZF

    Remarque : Source ne peut tre une valeur immdiate.

    j) linstruction IDIV ( Integer Divide)

    Syntaxe : IDIV Source

    Description : Effectue une division euclidienne dentiers signs.

    Si Sourceest un octet : AX est divis par Source, le quotient est plac dans AL et le restedans AH.

    Si Sourceest un mot : DX:AX est divis par Source, le quotient est plac dans AX et le

    reste dans DX.Si Sourceest un double mot : EDX:EAX est divis par Source, le quotient est plac dans

    EAX et le reste dans EDX.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    k) linstruction NEG ( Negation)

    Syntaxe : NEG Destination

    Description : Forme le complment 2 de Destination, i.e. prend loppos de Destination.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    Remarque : A ne pas confondre avec NOT, qui forme le complment 1.

    8. Les instructions logiques

    a) linstruction NOT ( Logical NOT)

    Syntaxe : NOT Destination

    Description : Effectue un NON logique bit bit sur Destination(i.e. chaque bit de Destinationestinvers).

    b) linstruction OR ( Logical OR)

    Syntaxe : OR Destination, Source

    Description : Effectue un OU logique inclusif bit bit entre Destinationet Source. Le rsultat est

    stock dans Destination.

    Indicateurs affects : CF, OF, PF, SF, ZF

  • 8/14/2019 Apprendre l'Assembleur

    48/71

    Remarque : Afin doptimiser la taille et les performances du programme, on peut utiliserlinstruction OR AX, AX la place de CMP AX, 0.En effet, un OU bit bit entre deux nombres identiques ne modifie pas Destination et estexcut infiniment plus rapidement quune soustraction. Comme les flags sont affects, lessauts conditionnels sont possibles.

    c) linstruction AND ( Logical AND)

    Syntaxe : AND Destination, Source

    Description : Effectue un ET logique bit bit entre Destinationet Source. Le rsultat est stockdans Destination.

    Indicateurs affects : CF, OF, PF, SF, ZF

    d) linstruction TEST ( Test for bit pattern)

    Syntaxe : TEST Destination, Source

    Description : Effectue un ET logique bit bit entre Destinationet Source. Le rsultat nest pasconserv, donc Destinationnest pas modifi. Seuls les flags sont affects.

    Cet oprateur est souvent utilis pour tester certains bits de Destination.

    Indicateurs affects : CF, OF, PF, SF, ZF

    Exemple :

    e) linstruction XOR ( Exclusive logical OR)

    Syntaxe : XOR Destination, Source

    Description : Effectue un OU logique exclusif bit bit entre Destinationet Source. Le rsultat eststock dans Destination.

    Indicateurs affects : CF, OF, PF, SF, ZF

    Remarque : Pour remettre un registre zro, il est prfrable de faire XOR AX, AX que MOVAX, 0. En effet, le rsultat est le mme mais la taille et surtout la vitesse dexcution de

  • 8/14/2019 Apprendre l'Assembleur

    49/71

    linstruction sont trs largement optimises.

    f) linstruction SHL ( Shift logical Left)

    Syntaxe : SHL Destination, Source

    Description : Dcale les bits de Destinationde Sourcepositions vers la gauche. Les bits les plus

    droite sont remplacs par des zros.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    Exemple : SHL AX, 4;permet de multiplier par 16 de faon infiniment plus rapide que MUL

    Mnmonique quivalent : SAL ( Shift Arithmetical Left)

    g) linstruction SHR ( Shift logical Right)

    Syntaxe : SHR Destination, Source

    Description : Dcale les bits de Destinationde Sourcepositions vers la droite. Les bits les plus gauche sont remplacs par des zros.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    Mnmonique quivalent : SAR ( Shift Arithmetical Right)

    h) linstruction ROL ( Rotate Left)

    Syntaxe : ROL Destination, Source

    Description : Effectue une rotation des bits de Destinationde Sourcepositions vers la gauche.Le dernier bit tre sorti gauche et tre rentr droite est plac dans CF. OF est mis 1 siet seulement si le signe de Destinationa chang.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    i) linstruction ROR ( Rotate Right)

    Syntaxe : ROR Destination, Source

    Description : Effectue une rotation des bits de Destinationde Sourcepositions vers la droite. Ledernier bit tre sorti droite et tre rentr gauche est plac dans CF. OF est mis 1 si etseulement si le signe de Destinationa chang.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    j) linstruction RCL ( Rotate through Carry Left)

    Syntaxe : RCL Destination, Source

    Description : Effectue une rotation des bits de Destinationde Sourcepositions vers la gauche.CF est utilis comme intermdiaire : chaque bit qui sort gauche est plac dans CF, et le

  • 8/14/2019 Apprendre l'Assembleur

    50/71

    contenu de CF est ensuite rinsr droite. OF est mis 1 si et seulement si le signe deDestinationa chang.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    k) linstruction RCR ( Rotate through Carry Right)

    Syntaxe : RCR Destination, Source

    Description : Effectue une rotation des bits de Destinationde Sourcepositions vers la droite. CFest utilis comme intermdiaire : chaque bit qui sort droite est plac dans CF, et le contenu deCF est ensuite rinsr gauche. OF est mis 1 si et seulement si le signe de Destinationachang.

    Indicateurs affects : AF, CF, OF, PF, SF, ZF

    9. Les instructions de manipulation des flags

    a) linstruction CLC ( Clear Carry flag)

    Syntaxe : CLC

    Description : Met CF 0.

    Indicateurs affects : CF

    b) linstruction STC ( Set Carry flag)

    Syntaxe : STC

    Description : Met CF 1.

    Indicateurs affects : CF

    c) linstruction CLD ( Clear Direction flag)

    Syntaxe : CLD

    Description : Met DF 0.

    Indicateurs affects : DF

    d) linstruction STD ( Set Direction flag)

    Syntaxe : STD

    Description : Met DF 1.

    Indicateurs affects : DF

    e) linstruction CLI ( Clear Interrupt flag)

  • 8/14/2019 Apprendre l'Assembleur

    51/71

    Syntaxe : CLI

    Description : Met IF 0.

    Indicateurs affects : IF

    f) linstruction STI ( Set Interrupt flag)

    Syntaxe : STI

    Description : Met IF 1.

    Indicateurs affects : IF

    g) linstruction CMC ( Complement Carry flag)

    Syntaxe : CMC

    Description : Inverse CF.

    Indicateurs affects : CF

    h) linstruction LAHF ( Load AH from Flags)

    Syntaxe : LAHF

    Description : Charge dans AH loctet de poids faible du registre des indicateurs.

    i) linstruction SAHF ( Store AH into Flags)

    Syntaxe : SAHF

    Description : Stocke les bits de AH dans le registre des indicateurs.

    10. Les instructions de gestion de la pile

    a) linstruction PUSH ( Push Word onto Stack)

    Syntaxe : PUSH Source

    Description : Empile le mot Source. SP est dcrment de 2.

    Remarques : Source ne peut tre une valeur immdiate. Il est possible dabrger votre codesource en crivant par exemple PUSH AX BX BP. Le compilateur crira alors trois foislinstruction PUSH du langage machine. Il est possible galement dempiler des doubles mots.

    b) linstruction POP ( Pop Word off Stack)

    Syntaxe : POP Destination

    Description : Dpile le mot qui se trouve au sommet de la pile et le place dans Destination. SP

  • 8/14/2019 Apprendre l'Assembleur

    52/71

    est incrment de 2.

    c) linstruction PUSHF ( Push Flags onto Stack)

    Syntaxe : PUSHF

    Description : Empile le registre des indicateurs. SP est dcrment de 2.

    Remarque : PUSHFD empile le registre des indicateurs cod sur 32 bits.

    d) linstruction POPF ( Pop Flags off Stack)

    Syntaxe : POPF

    Description : Dpile le mot qui se trouve au sommet de la pile et le place dans le registre desindicateurs. SP est incrment de 2.

    Indicateurs affects : Tous

    Remarque : POPFD est utilis pour un registre des indicateurs cod sur 32 bits.

    e) linstruction PUSHA ( Push All registers onto Stack)

    Syntaxe : PUSHA

    Description : Empile AX, BX, CX, DX, BP, SI, DI et SP.

    Remarque : PUSHAD est utilis pour des registres de 32 bits.

    f) linstruction POPA ( Pop All registers off Stack)

    Syntaxe : POPA

    Description : Restaure AX, BX, CX, DX, BP, SI, DI et SP partir de la pile.

    Remarque : POPAD est utilis pour des registres de 32 bits.

    11. Les instructions de gestion des chanes doctetsa) linstruction MOVSB ( Move String Byte)

    Syntaxe : MOVSB

    Description : Copie loctet adress par DS:SI ladresse ES:DI. Si DF = 0, alors DI et SI sontensuite incrments, sinon ils sont dcrments.

    Remarque : Pour copier plusieurs octets, faire REP MOVSB ( Repeat Move String Byte). Lenombre doctets copier doit tre transmis dans CX de mme que pour un LOOP.

    Exemple :

  • 8/14/2019 Apprendre l'Assembleur

    53/71

    b) linstruction SCASB ( Scan String Byte)

    Syntaxe : SCASB

    Description : Compare loctet adress par ES:DI avec AL. Les rsultats sont placs dans leregistre des indicateurs. Si DF = 0, alors DI est ensuite incrment, sinon il est dcrment.

    Remarques : Pour comparer plusieurs octets, faire REP SCASB ou REPE SCASB ( Repeatuntil Egal), ou encore REPZ SCASB ( Repeat until Zero). Ces trois prfixes sontquivalents.Le nombre doctets comparer doit tre transmis dans CX. La boucle ainsi cre sarrte si CX= 0 ou si le caractre point par ES:DI est le mme que celui contenu dans AL (i.e. si ZF = 1).On peut ainsi rechercher un caractre dans une chane.Pour rpter au contraire la comparaisonjusqu ce queZF = 0, cest--dire jusqu ce que ALet le caractre adress par ES:DI diffrent, utiliser REPNE ou REPNZ.

    Exemple :

  • 8/14/2019 Apprendre l'Assembleur

    54/71

  • 8/14/2019 Apprendre l'Assembleur

    55/71

    a) linstruction MOVSW ( Move String Word)

    Syntaxe : MOVSW

    Description : Copie le mot adress par DS:SI ladresse ES:DI. Si DF = 0, alors DI et SI sontensuite incrments de 2, sinon ils sont dcrments de 2.

    Remarque : Pour copier plusieurs mots, faire REP MOVSW. Le nombre de mots copier doittre transmis dans CX.

    b) linstruction SCASW ( Scan String Word)

    Syntaxe : SCASW

    Description : Compare le mot adress par ES:DI avec AX. Les rsultats sont placs dans leregistre des indicateurs. Si DF = 0, alors DI est ensuite incrment de 2, sinon il est dcrmentde 2.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour SCASB.

    c) linstruction LODSW ( Load String Word)

    Syntaxe : LODSW

    Description : Charge dans AX le mot adress par DS:SI. Si DF = 0, alors SI est ensuiteincrment de 2, sinon il est dcrment de 2.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour LODSB.

    d) linstruction STOSW ( Store String Word)

    Syntaxe : STOSW

    Description : Stocke le contenu de AX dans le mot adress par ES:DI. Si DF = 0, alors DI estensuite incrment de 2, sinon il est dcrment de 2.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour STOSB.

    e) linstruction CMPSW ( Compare String Word)

    Syntaxe : CMPSW

    Description : Compare le mot adress par DS:SI et celui adress par ES:DI. Si DF = 0, alors SIet DI sont ensuite incrments de 2, sinon ils sont dcrments de 2.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour CMPSB.

    13. Les instructions de gestion des chanes de doubles mots

    Elles traitent des doubles mots et leur nom se termine par un D.

  • 8/14/2019 Apprendre l'Assembleur

    56/71

    a) linstruction MOVSD ( Move String Double Word)

    Syntaxe : MOVSD

    Description : Copie le double mot adress par DS:SI ladresse ES:DI. Si DF = 0, alors DI et SIsont ensuite incrments de 4, sinon ils sont dcrments de 4.

    Remarque : Pour copier plusieurs doubles mots, faire REP MOVSD. Le nombre de doublesmots copier doit tre transmis dans CX.

    b) linstruction SCASD ( Scan String Double Word)

    Syntaxe : SCASD

    Description : Compare le double mot adress par ES:DI avec EAX. Les rsultats sont placsdans le registre des indicateurs. Si DF = 0, alors DI est ensuite incrment de 4, sinon il estdcrment de 4.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour SCASB.

    c) linstruction LODSD ( Load String Double Word)

    Syntaxe : LODSD

    Description : Charge dans EAX le double mot adress par DS:SI. Si DF = 0, alors SI est ensuiteincrment de 4, sinon il est dcrment de 4.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour LODSB.

    d) linstruction STOSD ( Store String Double Word)

    Syntaxe : STOSD

    Description : Stocke le contenu de EAX dans le double mot adress par ES:DI. Si DF = 0, alorsDI est ensuite incrment de 4, sinon il est dcrment de 4.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour STOSB.

    e) linstruction CMPSD ( Compare String Double Word)

    Syntaxe : CMPSD

    Description : Compare le double mot adress par DS:SI et celui adress par ES:DI. Si DF = 0,alors SI et DI sont ensuite incrments de 4, sinon ils sont dcrments de 4.

    Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour CMPSB.

    14. Les instructions dappel

    a) linstruction CALL ( Procedure Call)

  • 8/14/2019 Apprendre l'Assembleur

    57/71

    Syntaxe : CALL MaProc

    Description : Appel de procdure. Si MaProc se trouve dans un segment extrieur, leprocesseur empile CS. Ensuite, dans tous les cas, il empile IP et fait un saut ltiquetteMaProc.

    b) linstr