ASSEMBLEUR 8086 1 Introduction
Transcription
ASSEMBLEUR 8086 1 Introduction
ASSEMBLEUR 8086 1 Introduction 1.1 Architecture d'un ordinateur Un ordinateur de type PC est constitue d'elements assurant des fonctions precises : le calcul, la memoire, la circulation des informations(programmes et donnees), le contr^ole des dierents organes. Bus d’adresse Mémoire RAM Registre instruction Accumulateur UAL Registre d’adresse mémoire registres opérandes Registre de données de la mémoire Bus de données Principe d’une architecture de type PC Un programme est une suite de codes stockes en memoire. Chaque element de code en est extrait et stocke, au cours de l'execution d'un programme, dans une petite memoire elementaire ou registre : le registre d'instructions. Apres decodage, les donnees sont lues en memoire, circulent le longs de ls qu'on designe sous le nom de ligne omnibus ou plus simplement de bus : le bus des donnees; puis elles sont stockees dans des registres de donnees. De la, elles sont injectees dans la centrale de calcul (ou Unite Arithmetique et Logique UAL), qui represente le cur du microprocesseur. Le resultat est place dans un registre particulier qu'on appelle l'accumulateur, puis, eventuellement, range en memoire apres avoir parcouru le bus de donnees. Un contr^ole tres n du cadencement des dierentes parties de chaque operation est realise a l'aide d'une horloge extremement precise qui permet de synchroniser les dierents signaux qui parcourent l'architecture. 1.2 Niveaux de langage On distingue : { le niveau interne qui correspond aux commandes des dierents signaux de contr^ole des circuits. { le code machine: code du microprocesseur qu'il sait reconna^tre et auquel il associe une serie de commandes internes synchronisees par l'horloge. Par exemple, le code 41 a pour signication: ajouter 1 au contenu d'un registre appele AL. 1 { Le mnemonique ou assembleur. Programmer en code machine est peut pratique, et on prefere decrire des operations a realiser a l'aide de mots-cles qui rappelent la signication de cette operation. Un programme special ( pour nous TURBO-ASSEMBLEUR) compile ce langage. La compilation est une operation en 2 phases : apres verication de la validite du programme decrit en assembleur, ce dernier est traduit en code machine pr^et a ^etre execute. ( a une operation pres qu'on appele l'edition de liens). Par exemple, incrementer de 1 le registre AL s'ecrit en assembleur 8086: INC AL { les langages evolues : PASCAL, C, ADA, COBOL, .. .En PASCAL, par exemple, l'operation precedente pourrait s'ecrire : i:= i + 1 ; 1.3 Numeration 1.3.1 Representation des nombres L'atome d'information s'appele le bit et vaut 0 ou 1. Avec un bit, on peut coder 2 informations dierentes, deux etats : m^ale ou femelle, noir ou blanc, .. . Avec 2 bits, on peut coder 4 (22 ) etats ou congurations dierentes : 00, 01, 10 et 11. soient les 4 saisons, 4 chires, 4 situations particulieres .. . On a convenu tres t^ot de grouper les bits par 8 pour constituer un octet, ce qui permet de coder 28 nombres ou etats. Un octet permet de coder 256 valeurs dierentes, ce qui est susant, en occident, pour representer l'ensemble des caracteres d'un clavier de machine a ecrire. A chaque valeur sur 8 bits correspond un symbole alphanumerique. Plusieurs codes existent, mais le plus utilise en informatique, en tout cas sur un PC est le code ASCII. Dans ce code, le caractere A est code 65, a est code 97, le chire 0 est code 48. Enn, on regroupe frequemment les octets par 2, 4 ou plus, pour constituer des mots, doubles-mots, . . . On convient que le bit de poids le plus faible d'un nombre sera denomme \bit 0" et que le bit de poids le plus fort sera denomme \ bit 7" ou \bit 15", selon la longueur de la representation. 1.3.2 Conversion binaire-decimal Nous travaillons en numeration de position, ce qui signie que, dans n'importe quelle base de representation, un nombre s'ecrit toujours : n = X, d 1 k=0 i Pi b ou d est le nombre de chires, i un poids et b la base. Par exemple, en base 10, 2345 s'ecrit : 2 103 + 3 102 + 4 101 + 5 100 Un nombre binaire est une suite de 0 et de 1 de poids respectifs : 20, 21, 22 , etc .. . Ainsi 1101 a pour valeur en decimal: 1 23 + 1 22 + 0 21 + 1 20 a partir des poids forts, soit 1 + 4 + 8 = 1310 A l'inverse, les divisions successives d'un nombre decimal par 2 donnent les poids de sa representation binaire. p : : : : : 1.3.3 hexadecimal-decimal : : : L'hexadecimal est une representation en base 16 tres utilisee quand on programme en assembleur. Dans toute base, les poids, ne peuvent aller que de 0 a b-1. 2 De plus, ce sont toujours des chires, car le nombre 13 par exemple, dans une base b donnee, signie 3 unites et 1 fois la base a la puissance 1. En base 16, on ne peut plus trouver de chires pour representer les valeurs comprises entre 10 et 15. 10 a la signication: 0 unites et une seizaine. On utilise donc les lettres A, B,.. .F; A correspond au 10 decimal, B au 11 decimal, . .. et F au 15 decimal. Ainsi 2C hexa vaut 2*16+13, soit 4510. A l'inverse, la division par 16 fournit les poids de la representation hexa d'une valeur decimale. 1.3.4 hexadecimal-binaire A un \chire " hexadecimal correspondent 4 bits, car F = 1111. La correspondance est ainsi tres facile. Partant d'un nombre binaire, il sut de grouper ses bits par 4 a partir des poids faibles, puis de donner la correspondance hexadecimale de chacun des groupes. Par exemple: 11 1101 0110 1110 vaut 3D6E Un programmeur en assembleur doit savoir jongler avec l'ensemble de ces representations et codages ( auquels il doit bien souvent ajouter loctal). Ainsi la lettre `A' dont le code decimal en ASCII est 65 a pour representation binaire 01000001b et 41h en hexadecimal. 1.3.5 Notation des nombres en ASM86 An de permettre a l'assembleur de distinguer les dierentes bases de representation, les valeurs binaires sont accompagnees d'un b minuscule, les valeurs octales d'un o minuscules et les valeurs hexa d'un h minuscule. Pour eviter de plus les confusions avec les identicateurs ou mots-cles du langage, les valeurs hexadecimales dont le premier \chire " est une lettre sont precedees d'un 0. Exemples : mov al, 01110100b mov ah, 75h mov ax, 0BAD4h 2 Le 8086 2.1 La famille IAPx86 Il s'agit d'une famille de processeurs a compatibilite ascendante, c.a.d. que le code des plus anciens est toujours compris et correctement execute par les plus recents. { le 8086 dispose d'un bus de 16 bits pour les donnees. sa capacite d'adressage est de 1Mo et il est cadence a 4.77 ou 8 Mhz. { le 8088 est la version 8 bits du 8086. il a les m^emes caracteristiques, mais un assembleur plus reduit. { le 80286 est une machine 16 bits, pouvant adresser 8Mo de code et de donnees, cadence a 6,8,10,12 ou 16 Mhz. Il introduit 2 modes d'adressage ( reel ou protege). { le 80386 est un faux 32 bits, adressant 4Go et cadence a 16, 20 ou 25 Mhz. 3 { le 80486 est un vrai 32 bits dote d'une memoire cache integree et d'une unite de calcul en virgule ottante. { le 80586, appele pentium pour des raisons de protection commerciale, dispose d'un bus de donnees de 64 bits et est muni d'un dispositif de prevision des branchements. Il est constitue de 2 processeurs en pipe-line paralleles lui permettant d'executer deux instructions en m^eme temps. Son cadencement est envisage (en 1994) jusqu'a 150 MHZ. { le \P6", successeur du pentium, est annonce. Il sera constitue de 6 millions de transistors ( contre 275 000 pour le 386 , 1 million pour le 486 et 3 pour le pentium) et la dimension des traits de ses transistors sera de 0.6 microns (contre 11.5 pour le 386). Il pourra traiter 250 millions d'instructions par seconde. Dans la suite, nous ne nous interresserons qu'au 8086. 2.2 Les memoires du 8086 Le 8086 dipose de plusieurs memoires. La plus importante est la memoire de travail ou RAM (Random Access Memory). C'est elle qui contient la partie active du systeme, les programmes et les donnees. Il existe une memoire morte (ininscriptible), la ROM, qui contient le code binaire des instructions assembleur et les sequences correspondant aux dierentes interruptions.L'ordinateur dispose enn d'une troisieme memoire physiquement distincte de la RAM, la memoire d'Entrees/Sorties, permettant les echanges avec l'exterieur. La RAM est un bloc de 1 Mo d'adresses qui est decoupe de la maniere suivante: La partie basse des adresses est reservee pour le systeme. Au dessus du systeme, on trouve une zone qui est physiquement limite a 640Ko, dans la quelle on range les programmes en execution et les donnees actives : le tas. Au dessus du tas se trouve une pile, destinee a gerer les apels de procedures et les interruptions. Au dessus de la limite des 640Ko se situe la memoire graphique qui est physiquement situee sur la carte video. 1 Mo MEMOIRE VIDEO 640 Ko Pile disponible pour la pile ou le tas. Tas SYSTEME 0 4 2.2.1 Mecanisme d'adressage du 8086 Le 8086 peut adresser 1 Mo, soient des adresses allant de 0 a 0FFFFFh. Ceci pose un pobleme. On a vu que : { Un octet peut coder 256 valeurs ( de 0 a 255) { Un mot (16 bits) peut en coder 65536 ( de 0 a 65535) { Un double-mot (32 bits) peut coder 4 Mo. Comment a-t-on pu proceder pour qu'une une machine 16 bits puisse adresser davantage que 64 Ko? En realite, les adresses sont comptees par paquets de 64 Ko. Chacun de ces blocs d'adresse constitue un SEGMENT. La memoire est donc decoupee en un certain nombre de segments. Une adresse logique est constituee de 2 valeurs : un numero de segment et la valeur de l'oset=deplacemet par rapport au debut du segment. L'adresse physique du 8086 est representee sur 20 bits (veritable dimension de son bus d'adresses) soit: Valeur du segment (16 bits) * 16 (= d ecal ee 4 fois a gauche) + Valeur de l'Offset ( 16 bits) -------------------------------= adresse m emoire sur 20 bits, soit de 0 a 1Mo. On remarquera que la m^eme adresse absolue peut ^etre obtenue a partir de plusieurs adresses logiques dierentes. 2.3 Les ports d'E/S En plus de l'espace de 1Mo existe une memoire specialisee de 64 Ko destinee aux echanges avec l'exterieur (Reseau, imprimantes, ecrans, .. .) Cet echange se fait par l'intermediaire du port d'Entrees/Sorties (E/S en abrege). En pratique, on n'utilise qu'un petit nombre d'adresses au sein de cette memoire. Les dierents organes connectes a l'ordinateur connaissent la ou les adresses au niveaux desquelles se font les echanges qui les concernent. Il n'est donc pas recommande d'ecrire n'importe ou sans precaution. L'acces a cette memoire se fait a l'aide des instructions IN et OUT. 2.3.1 La memoire Video Les images video sont implantees en memoire RAM au dela des fatidiques 640 Ko qui constituent la limite de la memoire centrale ( A l'epoque, vers 1980, il semblait impossible que l'on ait jamais besoin d'atteindre une limite aussi Kolossale !) En fait, l'introduction de standards graphiques VGA, VGA etendus, ... a conduit les architectes a implanter la memoire graphique sur les cartes video elles-m^emes. Les constructeurs ne s'etant jamais entendu sur un standard, chaque carte a son propre mode de programmation. Une technique generale existe cependant, assez lourde, et qui oblige a passer par l'intermediaire d'une zone de la memoire d'E/S et de registres specialises de la carte graphique. 5 2.3.2 La pile La programmation d'un ordinateur necessite l'usage (d'au moins) une pile. Une pile est une structure lineaire dont on ne peut manipuler que le sommet, a l'image d'une pile d'assiettes : vouloir retirer une assiette du milieu conduit a la catastrophe. La seule methode d'acces consiste a empiler ou depiler des assiettes a partir du sommet de la pile. Une telle structure permet de conserver en memoire l'ordre selon lequel on y a stocke des informations. En les depilant, l'ordinateur se retrouve dans l'etat ou il etait avant les operations qui ont conduit a des empilements successifs. L'assembleur vous fera manipuler une pile qui est stockee \en fond de panier", c.a.d dans les adresses les plus hautes de la memoire. (correspondant aux 640 Ko). Une petite particularite : La base de la pile se trouve a l'adresse maximale, et elle s'accroit vers les adresses basses. A l'inverse, les programmes se developpent sur le \tas", en bas de memoire, juste au dessus de la zone reservee pour le systeme. Pile et Tas croissent donc a l'inverse l'un de l'autre. 2.4 Les registres Ce sont des mots de memoire de 16 bits c^ables de facon particuliere, qui permettent de retenir des informations au cours de leur manipulation par le programme. 2.4.1 Registres a usage general 15 4 registres peuvent se decomposer en 2 registres de 8 bits chacun. { AX (A pour accumulateur) joue le r^ole d'operande implicite dans de nombreuses operations : MUL, DIV, INC, . .. La partie de poids forts se nomme AH et celle de poids faibles AL ( H pour high et L pour low) 8 7 AH 0 AL Registre AX { BX (B pour base), qui se decompose en BH et BL, sert entre autre a pointer sur une adresse memoire. { CX (C pour compteur) se decompose en CH et CL et est utilise pour les boucles (loop) { DX donne DH et DL { il permet de pointer sur l'espace des E/S avec IN et OUT en contenant la valeur de l'adresse, comme le montre l'exemple suivant: MOV AL,20 MOV DX,1000 OUT DX, AL { il est utilise dans les multiplications et les divisions comme registre d'extension. { SI (Source Index) est souvent utilise comme pointeur sur une adresse memoire: MOV AL, [SI] Il est tres utilise avec les instructions de traitement de cha^ne (LODS) 6 { DI (Destination Index) permet comme SI de pointer sur des adresses memoire. Il est aussi tres utilise pour les traitements de cha^ne (avec STOS) { BP (Base Pointer) sert de pointeur sur l'adresse memoire correspondant a la base de la pile, et permet en fait d'atteindre n'importe quel element de celle-ci : MOV AX, [BP+4] { SP (Stack Pointer) pointe sur le sommet de la pile. Son contenu est automatiquement gere par les instructions PUSH et POP d'empilage et de desempilage. 2.4.2 Registres speciaux { IP (Instruction Pointer) contient l'adresse de l'instruction qui suit celle qui est en cours d'execution, c'est-a-dire la prochaine a devoir ^etre executee en dehors des cas de branchement. { DS (Data Segment) pointe sur l'adresse de debut du segment qui contient les donnees. Un segment est une suite de 65536 adresses. Implicitement, BX et SI, lorsqu'ils servent de pointeur, sont prexes par DS. Une adresse est donc completement denie par un couple : DS:BX ou DS:SI Le nom du segment de donnees standard est DATA. Pour charger DS, il faut obligatoirement utiliser AX ainsi: MOV AX, @DATA MOV DS, AX { CS (Code Segment) pointe sur le segment contenant le code du programme. { ES (Extra Segment) permet de pointer sur un segment supplementaire deni par le programmeur. Il se charge par l'intermediaire de AX comme DS. { SS (Stack Segment) segment contenant la pile. 2.4.3 Le registre indicateur (Flag Register) Il est utilise pour stocker des etats particulier du microprocesseur en cours de fonctionnement (le signe de la derniere operation eectuee, l'existence d'une retenue en cours de propagation, .. .) Quelques bits seulement de ce registre ont une signication et sont nommes: CF est l'indicateur de retenue (Carry Flag), OF l'indicateur de debordement (Overow Flag), ... O D I Overflow Direction Interrupt Trap T S Z A P C Carry Parity Auxiliary carry Zero Sign Ce registre est contr^ole par des instructions particulieres, par exemple: CLC STI CLD STD : : : : mise mise mise mise a a a a z ero 1 de 0 de 1 de de CF (Clear C). IF ( Set I) DF DF 7 Ce registre est modie par les instructions arithmetiques et logiques, ainsi que par les comparaisons. 2.5 Les interruptions APPLICATION Les actions sur l’infrastructure matérielle se font par interruptions. DOS Le DOS exploite les primitives du BIOS BIOS infrastructure matérielle Une interruption est generee par l'instruction INT suivie du numero d'un service. Le principal service du DOS est 21h. Le BIOS dispose de nombreux services correspondant aux dispositifs qu'il commande ( ecran, contr^oleur de disque). A chaque interruption est associe un ensemble de fonctions du systeme. Le numero de la fonction se charge toujours dans AH. Selon la fonction, d'autres registres peuvent aussi ^etre utilises. Exemples de fonctions : { Pour desactiver un programme et revenir au DOS : Fonction 4Ch { Attente d'un caractere : Fonction 1 du DOS (service 21h). le caractere recu est dans AL. { Achage d'un octet : Fonction 2 du service 21h. le caractere a acher est dans DL. { Positionner le curseur : Fonction 2 du BIOS ( service 10h); le numero de ligne est place dans DH, le numero de colonne dans DL et le numero de page d'ecran dans BH. 8 3 Analyse de programmes en assembleur 3.1 Exemples 3.1.1 Fichier: ADDITION.ASM ; ; ; ; ; ; Ce programme r ealise l'addition de deux nombres rentr es au clavier chiffre apr es chiffre et affiche le r esultat. Les chiffres lus sont des caract eres. Il faut restituer la valeur d ecimale de chacun d'eux, stocker les nombres obtenus sur 4 octets maximum et additionner les octets correspondants de chaque nombre en propageant la retenue. DOSSEG .MODEL small .STACK 100h .DATA num1 DB 4 dup(0) ; premier nombre num2 DB 4 dup(0) ; second nombre num3 DB 4 dup(0) ; r esultat chaine1 DB 'TAPEZ LE PREMIER NOMBRE : ','$' chaine2 DB 13,10, 'TAPEZ LE SECOND NOMBRE : ','$' chaine3 DB 13,10,' RESULTAT : ','$' .CODE ;********************************************************************* ; Proc edure de lecture de nombres cod es sur 4 octets. * ; Les op erandes sont lues dans l'ordre des poids d ecroissants. * ; La pile permet de les utiliser selon les poids croissants. * ;********************************************************************* lect PROC mov ah,01 mov cx,0 boucle_lecture: int 21h cmp al,0Dh je rangement push ax inc cx jmp boucle_lecture rangement: add di,3 boucle_rangement: pop ax sub al,30h mov bl,al dec cx cmp cx,0 je suite pop ax sub al,30h push cx mov cl,4 shl ax,cl pop cx ; code fonction de lecture d'un caractere. ; mise a 0 du compteur. ; ; ; ; ; lecture a-t-on lu un retour-charriot ? OUI => on range les valeurs lues. sinon on empile le caractere dans un mot. on compte un ASCII de plus ; rangement du nombre lu. ; on se place en fin de zone de stockage. ; ; ; ; ; ; ; ; ; ; ; ; d epiler un code ASCII conversion en valeur d ecimale stockage dans BL on d ecr emente CX pour comper l'octet d epil e si CX =0 ... ... c'est fini sinon on d epile l'ASCII suivant. conversion en valeur d ecimale sauvegarde de CX (compteur d'ASCII lus ) on compte 4 d ecalages pour le ranger ... ... dans la partie droite de AL. restitution de CX 9 or bl,al suite: mov [di],bl cmp cx,0 je fin_lect dec di loop boucle_rangement fin_lect: ret lect ENDP ; on accole le chiffre au pr ec edent ; sauvegarde en m emoire par position d ecroisante ; on pointe sur la position pr ec edente ; jusqu' a ce que CX soit nul DebutProgramme: mov ax,@data mov ds,ax mov ah,9 mov dx, OFFSET chaine1 int 21h mov di,OFFSET num1 call lect mov ah,9 mov dx, OFFSET chaine2 int 21h mov di,OFFSET num2 call lect mov ah,9 mov dx, OFFSET chaine3 int 21h call Addition mov ah,4Ch int 21h Addition PROC mov si,OFFSET num1 mov di,OFFSET num2 add si,4 add di,4 mov cx,4 mov bx,OFFSET num3 add bx,4 clc boucle_addition: dec si dec di dec bx mov al,[di] adc al,[si] daa mov [bx],al loop boucle_addition mov di,OFFSET num3 mov cx,4 mov ah,02 affich: ;la fonction de lecture n 9 exige ; des cha^ nes termin ees par un '$' ; affichage du 1 message ; affichage du 2 message ; affichage du 3 message ; retour au DOS et ... ; ... FIN DU PROGRAMME ; SI et DI pointent sur les 2 op erandes ; on se place en queue des op erandes ; BX pointe sur le r esultat ; et on se place sur l'octet de poids faible ; mise a z ero du bit de retenue (CF) ; addition avec prise en compte de la retenue ; ajustement en codage BCD ; stockage de l'octet du r esultat ; ; ; ; on pointe sur le r esultat pour l'afficher le r esultat est sur 4 octets code fonction d' ecriture d'un caract ere boucle d'affichage 10 mov dl,[di] mov bl,dl push cx mov cl,4 shr dl,cl ; d ecal e a droite add dl,30h int 21h mov dl,bl and dl,0Fh add dl,30h int 21h inc di pop cx loop affich FIN: ret Addition ENDP END ; sauvegarde du compteur d'octets affich es ; le demi-octet de gauche (poids forts) est ; ; ; ; ; ; transformation du chiffre en son code ASCII impression sur l' ecran on r ecup ere l'octet initial on masque le demi-octet de gauche d ej a trait e transformation num erique -> ASCII affichage ecran ; r ecup eration du nombre de tours de boucle DebutProgramme 3.1.2 Fichier: DIAGONALE.ASM ; Trac e d'une diagonale rouge sur fond bleu-clair a l' ecran ; en mode graphique DOSSEG .MODEL small .STACK 200h .DATA NUM DB 200 .CODE mov ax,@data mov ds,ax mov ah,0 mov al,4 ; mise de l' ecran au mode graphique 320*200 couleur int 10h ; appel au BIOS mov mov mov int ah,0Bh bh,0 bl,9 10h mov ah,0Bh mov bh,1 mov bl,0 int 10h mov cx,200 diag: push cx mov ah,0Ch mov al,2 push ax mov dx,cx push dx ; choix d'une palette de couleurs ; fond bleu-clair ; palette de couleurs ; palette n 0 (vert, rouge,jaune) ; 200 pixels (largeur de l' ecran) a tracer ; affichage d'un point (pixel) ; couleur du point (rouge = 2 eme de la palette) ; sauvegardes de registres 11 mov ax,dx mov dh,32 mul dh mov dx,0 mov bx,20 div bx mov cx,ax pop dx pop ax int 10h pop cx loop diag attente: mov ah,1 int 21h fin: mov ah,0 mov al,3 int 10h mov ah,4Ch int 21h END ; ; ; ; DX doit contenir le num ero de la ligne du pixel on multiplie par 32/20 ... ... pour tenir compte du caract ere rectangulaire ... ... de l'espace d'affichage ; CX doit contenir le num ero de la colonne du pixel ; appel au BIOS pour allumer le point a l' ecran ; r ecup eration du nombre de points restant a tracer ; Retour au mode TEXTE ; retour au DOS 3.1.3 PROGRAMMES MULTI{MODULES ;**************************************************************** ;* EXEMPLE DE PROGRAMMATION MULTI-MODULES * ;**************************************************************** ;* PROGRAMME PRINCIPAL * ;* Compilation : TASM princip * ;* TASM routine * ;* Edition des liens : TLINK princip + routine * ;**************************************************************** DOSSEG .MODEL small .STACK 200h .DATA chaine1 DB 'VIVE ',0 chaine2 DB 'LA LICENCE INFO !',0dh,0ah,'$',0 GLOBAL ChaineFinale : BYTE; ChaineFinale DB 50 DUP5? .CODE GLOBAL ConcateneChaine : PROC mov ax, @data mov ds,ax mov ax,OFFSET chaine1 mov bx, OFFSET chaine2 call ConcateneChaine ; Assemble les 2 chaines en une seule ; L'adresse des chaines composantes ; doit ^ etre pass ee par AX et BX. mov ah,09h ; Fonction d' ecriture d'une cha^ ne ; termin ee par le caract ere '$' mov dx,OFFSET ChaineFinale 12 int 21h ; Affiche la chaine a l' ecran. mov ah,4Ch int 21h END ; Retour au DOS. ;**************************************************************** ;* Module dans un fichier s epar e * ;* ConcateneChaine * ;* Concat ene deux cha^ nes et range le * ;* r esultat dans la variable globale * ;* ChaineFinale. * ;* ENTREES : DS:AX = pointeur vers la premi ere cha^ ne * ;* DS:BX = pointeur vers la seconde cha^ ne * ;* SORTIES : n eant * ;* REGISTRES MODIFIES : AL, SI, DI, ES * ;**************************************************************** DOSSEG .MODEL small .DATA GLOBAL ChaineFinale : BYTE .CODE GLOBAL ConcateneChaine ConcateneChaine PROC cld ; on fixe le sens de parcours ; des chaines mov di,SEG ChaineFinale mov es,di mov di,OFFSET ChaineFinale ; ES:DI pointe sur le r esultat mov si,ax ; Adresse de la chaine 1 dans SI boucle1 : lodsb ; On prend 1 caractere dans chaine1 and al,al ; Est-ce un z ero ? jz traitechaine ; OUI -> parcours termin e stosb ; NON -> on copie le caractere dans ; ChaineFinale ... jmp boucle1 ; ... et on recommence traitechaine : mov si,bx ; Adresse de la 2eme chaine dans SI boucle2: lodsb ; On prend un caractere de la chaine2 stosb ; On le copie dans ChaineFinale, z ero ; compris. and al,al ; etait-ce le z ero ? jnz boucle2 ; NON -> on recommence ret ; OUI -> c'est fini ; On retourne au programme appelant. ConcateneChaine ENDP END 13 3.2 Structure d'une ligne [Label:] [Instruction|Directive] [Op erandes] [; commentaire] 3.2.1 Les labels Les labels sont formes de chires, de lettres et des caracteres : , @, $ et? Il faut s'obliger a ecrire des programmes lisibles. Comparez: CMP AL, 'O' avec CMP AL, OUI JZ ET1 avec JZ ReponsePositive 3.2.2 Principales directives { { delimite la n du texte source END etiquette permet de lancer le programme a cette etiquette. Par defaut, la premiere instruction executable est celle qui suit la directive .CODE { .MODEL, .DATA, .STACK, .CODE sont des directives qui seront explicitees par la suite. END 3.2.3 Instructions Elles sont constituees de mnemoniques de 3 a 5 lettres comme: MOV, MOVSB, MOVSW par exemple. Les operandes sont des registres, des variables declarees dans la partie delimitee par .DATA, des constantes. On trouve des instructions a operande implicite: MUL BH 3.2.4 Expressions et operateurs { LENGTH renvoie le nombre d'elements d'une donnee declaree avec l'operateur de duplication DUP (tableaux). { SIZE renvoie le nombre d'octets d'un element de donnees (cha^ne de caracteres). { WIDTH renvoie la taille d'un enregistrement ou d'un champ d'enregistrement exprimee en nombre de bits. { HIGH et LOW permettent de selectionner les parties hautes et basses d'une constante, d'une expression ou d'une adresse. { OFFSET, SEG permettent de separer les composantes d'une adresse. { PTR est utilise pour contr^oler le transtypage d'une expression. { TYPE renvoit un nombre indiquant la taille ou le type d'un symbole. { MOD est l'operateur modulo { SHL, SHR sont des operateurs de decalage. { EQ, GE, GT, LE, LT, NE sont des operateurs de comparaison. { NOT, OR, AND, XOR sont les operateurs logiques classiques. { LARGE denit la partie deplacement d'une expression comme etant sur 32 bits, tandis que SMALL la denit sur 16 bits. 14 { SHORT force une expression a ^etre un pointeur de type proche. { on a de plus les operateurs arithmetiques: +, -, *, / Exemples : MOV MOV MOV mov MOV MOV val, 1234h AH, HIGH val AL, LOW val AX, OFFSET var+((4*2)-3) BYTE PTR [BX],1 AL, SIZE var 4 Les directives Il y a 2 familles de directives selon le mode de segmentation (standard ou simplie) { standard : pour de programmes de grande taille, developpes completement en assembleur.( ca a existe : Systemes, CAO, SGBD) { simplie : Pour de petits modules independants, eventuellement associes a un programme en langage evolue. C'est ce dernier mode que nous utiliserons et que nous allons exposer. { DOSSEG : ordonne les segments selon la convention MICROSOFT et permet la compatibilite avec MASM. Il faut l'utiliser quand on interface ASM avec ADA ALSYS. { .MODEL selectionne le modele de memoire. Il y a 6 modeles dierents : { TINY : Code et donnees sont sur un m^eme segment de 64Ko. Les sauts se font au sein de ce segment. { SMALL : code et donnees sont sur un segment chacun. { MEDIUM : Le code est sur plusieurs segments. les donnees sur un seul segment. { COMPACT : Le code est sur 64Ko, les donnees sur plusieurs segments. { LARGE: Code et donnees sont multisegment, mais une structure de donnee ( tableau par exemple) doit tenir sur un seul segment. { HUGE : Id. mais les structures de donnees sont multi-segment. Nous travaillerons toujours en modele SMALL. { .STACK permet de dimensionner la pile. Cette pile est indispensable, et sauf cas exceptionnel, elle doit toujours ^etre presente et susamment dimensionnee. { .DATA permet de denir les donnees simples ou complexes de l'application. { .CODE precede les instructions du programme qui se termine par la directive .END 15 5 Declaration des donnees 5.1 Donnees initialisees 5.1.1 Donnees simples DB (Data Byte) denit une donnee sur 1 octet, DW (Data Word) sur 1 mot ( 2 octets), DD (Data Double) un double mot, DQ pour 8 octets, DT pour 10 octets. V1 DB 'A' V2 DW 380 V3 DD 4BFCh 5.1.2 Tableaux TAB DW 0,1,2,3,4 MATRICE DD 0,1,2 DD 3,4,5 DD 6,7,8 T DW 256 DUP(0) ChaineVide DB 10 DUP(' ') Le prexe DUP permet de dupliquer n fois l'argument entre parentheses. 5.1.3 Cha^nes CH1 CH2 CH3 CH4 DB DB DB DB 'A', 'B', 'C', 'D' 'ABCD' 'Bonjour',13,10 'Salut', 0Dh,0Ah,$ Les declarations de CH1 et CH2 ont le m^eme resultat. les valeurs 0Dh=13, 0Ah=10 correspondent aux codes ASCII commandant le saut a la ligne ( Carriage return et Line Feed). Le $ est utilise pour acher a l'ecran la cha^ne a l'aide de la fonction 9 du DOS : MOV AH,9 MOV DX, OFFSET CH4 INT 21h REM : BUF DW 10 DUP(0) PTB DW BUF initialise la variable PTB utilisee ici comme pointeur avec la valeur de BUF, qui est l'adresse de BUF(0). MOV AX, OFFSET BUF MOV AX,[PTB] Ces deux instructions chargent dans AX l'adresse de BUF. 16 5.2 Donnees non initialisees La reservation de place en memoire se fait tres simplement sur le modele suivant: BUF DB 10 DUP(?) r eserve 10 octets pour BUF. 5.3 Directive EQU Elle permet d'aecter une valeur a un label ( qui ne pourra plus ^etre modiee) reponse EQU 'O' LongueurMax EQU 1000 Il faut s'obliger a utiliser le plus possible des labels lorsqu'on programme en assembleur. Il est en eet plus facile de lire par exemple: CMP AL, REPONSE que: CMP AL, 'O' Des constantes peuvent ainsi en denir d'autres : zone EQU 10 debut EQU (zone +2) fin EQU (zone + 50 Cette directive est aussi tres utile pour declarer des messages a acher: message EQU 'Donnez votre r eponse (O/N) : ' Enn, cette directive permet de rendre plus lisible des manipulations par adressage indirect: .DATA temp EQU [BP+2] i EQU [BP+4] j EQU [BP+6] k EQU [BP+8] .CODE Somme3 PROC PUSH BP MOV BP,SP SUB SP,2 MOV AX,i ADD AX,j MOV temp,AX MOV AX,k ADD AX,temp MOV SP,BP POP BP RET Somme3 ENDP ; BP pointe sur le sommet de pile ; SP pointe sur le mot pr ec edant Ce programme est certainement plus lisible que s'il presentait explicitement les manipulations de la pile. La directive = est identique a EQU, a ceci pres qu'elle permet de modier la valeur d'initialisation en cours d'execution. 17 5.3.1 Calcul de la longueur d'un vecteur ou d'une cha^ne Il est dicile et maladroit de compter le nombre de valeurs pour prexer l'operateur DUP. Il est preferable d'utiliser un label. Tout identicateur, en informatique, represente en general l'adresse de la valeur qu'il represente. Ainsi, un label correspond a la valeur de l'adresse au sein du segment de la position qu'il occupe dans le programme. Le m^eme r^ole est tenu par la variable $, qui represente l'adresse courante dans le segment en cours d'assemblage. Dans l'exemple qui suit, $ repere l'adresse du dernier mot de TABLE : table DW 50 DUP(0) FinTable Label Word Longueur DW (FinTable-Table) ou encore table DW 50 DUP(0) longueur EQU ($-table) 6 Transferts de donnees et modes d'adressage 6.1 Transferts Ils se font par l'instruction MOV destination, source La destination peut ^etre representee par des registres ou des variables; la source par des registres, des variables ou des constantes. Des expressions entre crochets indiquent que l'operande correspond a la valeur contenue a l'adresse calculee dans les crochets. Soit Var une cha^ne implantee a l'adresse 100 et qui vaut: 'ABCDEF'. Les 3 instructions suivantes sont equivalentes : MOV AL, [var+4] MOV AL, [104] MOV AL, [100+4] Toutes les 3 chargent le caractere 'E' dans AL. (le caractere d'adresse 0 est 'A'). Mais, MOV AL, var MOV AL, [VAR] ont le m^eme eet, car le nom d'une variable repere l'adresse de sa valeur. 6.2 Adressage direct Une position memoire est reperee par le nom d'une variable ou une combinaison nom-constante. Ce mode n'est pas tres souple, car l'adresse evaluee reste xe. MOV AX,[100+12] MOV BX,DS:[50] 18 6.3 Adressage indirect On utilise a cet eet un registre contenant l'adresse de base, a laquelle on ajoute un deplacement. Reprenons l'exemple precedent : MOV BX, OFFSET var + 4 MOV AL, [BX] Une fois encore, nous chargeons 'E' dans AL. D BX AL E 104 E F Ce mode d'adressage, contrairement au precedent, permet de balayer dynamiquement une liste d'adresses : MOV BX, OFFSET chaine boucle: MOV AL, [BX] CMP AL,0 ; le caract ere est-il nul ? JZ fin ; si OUI, c'est termin e INC BX ; on passe a l'adresse suivante JMP boucle ; si NON, on poursuit le balayage fin: DEC BX ; on revient sur le dernier caract ere ... MOV AL, [BX] ; ... qu'on charge dans AL cette fois-ci, nous balayons une variable chaine, terminee par le code ASCII nul, et en sortant, nous placons le dernier caractere non nul dans AL. Pour l'adressage indirect, on peut utiliser exclusivement les registres : BX, BP, SI et DI. Il existe 16 facons d'utiliser le mode indirect. La forme generale est : [registre de base +/- registre index +/- deplacement] [depl] [BX] [SI] [DI] [BX+SI] [BX+DI] [BP + SI] [BP + DI] [BP + depl] [BX+depl] [SI [DI [BX [BX [BP + + + + + depl] depl] SI + depl] DI + depl] SI + depl] [BP + DI + depl] Les expressions utilisant BX pointent sur la RAM (c-a-d sur le segment courant de celle-ci, correspondant generalement a la valeur de DS), celles utilisant BP pointent sur la pile. ici BX et [BX] ont des signications dierentes; BX correspond au contenu du registre (qui peut ^etre une adresse), alors que [BX] est la valeur dont l'adresse est dans BX. Les expressions qui suivent sont equivalentes : .DATA chaine DB 'ABCDEF' .CODE MOV AX,@DATA MOV DS,AX 19 ..... MOV SI,OFFSET chaine+4 MOV AL,[SI] ....... MOV SI,4 MOV AL, [chaine + SI] ....... MOV BX, OFFSET chaine MOV AL,[BX + 4] ....... MOV SI,4 MOV BX,OFFSET chaine MOV AL,[BX + SI] 7 Manipulation des donnees 7.1 Implicite MOV AL, BL ou MOV AL, 1 transf erent necessairement des octets, car le registre destinataire est un registre 8 bits. De m^eme: MOV AX, 1 transf ere un mot de valeur 1 dans le registre 16 bits AX. Considerons : var DB ? ... MOV [var], 'A' Cette aectation est sans ambigute non plus, car le nombre d'octets que permet d'adresser [var] a ete specie a la declaration par la directive DB. Il susbsite cependant des ambigutes , comme par exemple: MOV [BX],1 : on ne peut decider ici si l'on range la valeur 1 dans un octet ou dans un mot. Une telle instruction generera un message d'erreur de la part du compilateur. 7.2 mecanismes de conversion On leve les ambigutes a l'aide des operateurs BYTE PTR et WORD PTR MOV BYTE PTR [BX], 1 MOV WORD PTR [BX], 1 Ces operateurs permettent de traiter une variable selon un format dierent de celui correspondant a sa declaration : var DD ? ...... MOV WORD PTR [var], AX MOV WORD PTR [var+2], DX La variable var declaree comme double-mot est traitee ici comme si l'on avait en fait deux mots independants. 7.3 Donnees signees et non signees C'est au programmeur de faire la distinction, car il ne s'agit que d'une convention et d'un codage particulier. Ainsi, 0FFFFh peut-il representer aussi bien 65 535 que -1 ! 20 La representation binaire des nombres entiers contenus dans un registre fournit un nombre continu de valeurs : on passe de 65 535 a 0 en ajoutant 1, en representation non signee. Et, en representation signee, (dans laquelle le bit de poids fort designe le signe , positif s'il est nul), 0FFFEh corespond a la valeur decimale -2. Certaines instructions assembleur ne fonctionne pas de la m^eme maniere selon que le bit de poids fort est considere comme un bit de signe ou un poids numerique. 7.3.1 Conversion d'un octet non signe en un mot On force l'octet de poids fort a 0 : MOV CL, 12 MOV AL, CL MOV AH, 0 ; le mot de valeur 12 est dans AX 7.3.2 Conversion d'un octet signe en un mot On utilise l'instruction CBW (Convert Byte to Word). L'octet signe doit-^etre obligatoirement dans AL : MOV DH, -1 MOV AL, DH CBW MOV DX, AX ; le mot de valeur -1 est dans DX 7.3.3 Conversion d,un mot signe en double-mot On utilise l'instruction: CWD, le mot etant au depart dans AX : MOV AX, -1 CWD ; les poids forts sont dans DX 7.4 Manipulations de la pile Elles se font par les instructions PUSH (empiler) et POP (depiler) lorsqu'il s'agit de modier la structure de la pile. Il est possible egalement, pour lire ou modier des valeurs dans la pile, d'utiliser l'adressage indirect avec : [BP + deplacement]. 7.5 Entrees/Sorties Elles sont eectuees par IN et OUT. Les adresses sont dans DX. AL et AX sont les seuls registres autorises pour les operandes : MOV DX, 100h IN AL, DX MOV DX, 100h MOV AL, 0Fh OUT DX, AL 8 Instructions arithmetiques 8.1 ADD et SUB Les additions et soustractions se font sur 8 ou 16 bits selon les operandes. Les operations 32 bits ou plus doivent ^etre ecrites par le programmeur en eectuant le transfert des retenues avec ADC (ADd with Cary) et SBB (SuB with Borrow). ADD AX, BX 21 ADC DX, CX ; r ealise DX:AX := DX:AX + CX:BX de m^eme: SUB AX,BX SBB DX,CX ; r ealise DX:AX := DX:AX - CX:BX 8.2 Incrementation/decrementation Par INC et DEC. ADD AX, 1 occupe 3 octets; INC AX n'en occupe qu'un et est plus rapide. De m^eme, il vaut mieux ecrire deux fois de suite INC AX que ADD AX, 2. 8.3 Multiplication/division La multiplication est une instruction dans laquelle l'accumulateur est un operande implicite. MUL var : si var est une variable 8 bits, AL est op erande implicite, et les 16 bits du resultat sont ranges dans AX. si var est une variable 16 bits, AX est operande implicite et les 32 bits du resultat sont ranges dans le couple DX:AX MOV AL, 25 MOV DH, 40 MUL DH ....... MOV AX, 1000 MUL AX ; AL op erande implicite ; AX r esultat implicite ; AX contient 1000 ; calcul de AX au carr e. r esultat dans DX:AX Dans le cas de valeurs signees, il faut utiliser IMUL : MOV AL, -2 MOV AH, 10 IMUL AH ; on a -20 dans AX 8.3.1 Division d'un mot par un octet Le mot est dans AX, l'octet dans un registre ou en memoire. Le quotient est stocke dans AL et le reste dans AH : MOV AX, 51 MOV DL, 10 DIV DL ; le reste 1 est dans AH, le quotient 5 dans AL 8.3.2 Division d'un double-mot par un mot DX sert de registre d'extension; le double-mot est dans DX:AX, le mot dans un registre ou en memoire. Le quotient est range dans AX et le reste dans DX : MOV MOV MOV DIV AX, 2 DX, 1 BX, 10h BX ; 1002h est dans DX:AX ; 10h dans BX ; r esultat 100h dans AX, reste 2 dans DX 22 Pour les donnees signees, il faut utiliser IDIV: MOV AX, -545 CWD IDIV 100 ; place -545 dans DX:AX ; quotient -5 dans AX, reste -45 dans DX 8.4 Negation On utilise l'instruction NEG registre g en eral ou m emoire 9 Operations logiques L'instruction AND permet de masquer des valeurs : MOV AL, var AND AL, 0Fh ; ne retient que les 4 bits de poids faible de AL l'instruction OR peut ^etre utilisee pour forcer des bits a 1: MOV AL, var OR AL, 0Fh ; force les bits de poids faible a 1 l'instruction XOR permet d'inverser les bits d'un registre ou de les mettre plus rapidement a zero que ne le fait un MOV : XOR AX, AX ; remise a 0 repide de AX ..... MOV BL, 1011 0001b NOT BL ; BL = 0100 1110 XOR BL, 0FFh ; BL reprend sa valeur initiale 10 Decalages et rotations 10.1 Logiques SHL (Shift Left) eectue un decalage a gauche des bits. Le bit de poids fort se retrouve dans CF et un 0 est introduit en bit de poids faible. SHL AL, 1 Aucun autre op erande que 1 n'est accepte ! si l'on veut faire plusieurs decalages successifs, il faut ecrire autant de fois SHL registre,1 Une facon plus elegante d'operer consiste a utiliser CL dans son r^ole de compteur: MOV CL,4 SHL AX,CL ; effectue 4 d ecalages de AX Le decalage a gauche revient a faire une multiplication par 2 d'une valeur non signee. SHR (Shift Right) opere de facon analogue a droite. Le resultat est la division par 2 d'une valeur non signee. 23 10.2 Arithmetiques SAR(Shift Arithmetic Right): le bit de poids fort est recopie. le bit 0 transfere dans CF. Cette operation, qui preserve le bit de signe, permet de faire une division par 2 de valeurs signees. La m^eme operation est realisee a gauche par SAL. ROR(ROtation Right) eectue une permutation vers la droite. le bit de poids faible se retrouve dans CF. Cette operation permet de recadrer des bits dans un mot ou un octet. A gauche, l'instruction est ROL. RCR(Rotation with Carry Right) permet une permutation avec prise en compte de la retenue, utile par exemple dans le cas de decalages d'operandes etendus sur plusieurs mots. L'operation symetrique est RCL. 15 0 CF SHL 15 0 0 CF SAR 15 0 15 0 CF ROR CF RCR Toutes ces instructions n'operent que sur un bit a la fois, ou sur le nombre de positions speciees par CL. 11 Sauts 11.1 Inconditionnels JMP(jump) est l'equivalent d'un GOTO. Cette instruction permet de sauter a une adresse representee sur 16 bits, au sein du segment de code donc. L'adresse de saut est reperee par une etiquette. Dans les cas ou l'on cherche a economiser du code, on peut utiliser JMP SHORT etiquette qui correspond a un saut de 127 octets. Hors contrainte de ce type, TASM optimise l'adresse selon le cas. 11.2 Conditionnels Ils s'eectuent apres une comparaison CMP. CMP est identique a SUB, mais ne produit pas de resultat; il possitionne seulement les ags. Les sauts sont toujours courts (127 octets), et il faut prendre garde que l'etiquette puisse eectivement ^etre atteinte. 24 INSTRUCTION pour valeurs non signees JB/JNAE JAE/JNB JBE/JNA JA/JNBE JE/JZ JNE/JNZ pour valeurs signees JL/JNGE JGE/JNL JLE/JNG JG/JNLE JP/JPE JNP/JNPO JS JNS JC JNC JO JNO Exemples : MOV AH, 1 INT 21h CMP AL, 'A' JE suite ..... suite: ..... Conditions de saut Indicateurs below/ not above or equal above or equal/not below below or equal above/not below or equal equal/zero not equal/not zero CF = 1 CF=0 CF=1 et ZF=1 less than/not greater than greater or equal/not less than less or equal/not greater than greater than/not less or equal Parity even (paire) Parity odd (impaire) signe non signe retenue pas de retenue overow pas d'overow SF=NOT OF SF=OF ZF=1 ou SF=NOT OF ZF=0 ou SF=OF PF=1 PF=0 SF=1 SF=0 CF=1 CF=0 OF=1 OF=0 ZF=1 ZF=0 ; lecture d'un octet rang e dans AL ; Si l'octet lu est un 'A' on va a suite, sinon ... ; on poursuit en s equence Dans l'exemple qui suit, on interprete de 2 facons dierentes l'octet de valeur 130. En representation non signe, il correspond au code ASCII de 'e'. En representation signee, il vaut -2. Dans les deux cas, le saut n'a lieu que parce que la valeur dans AL est bien superieure (au sens de chaque convention de signe) a la constante 127 sur laquelle porte la comparaison: MOV AL,130 CMP AL, 127 JA LettreAccentuee ... MOV AL,130 CMP AL,127 JG ValeurNegative ... 12 Boucles 12.1 Boucle POUR On utilise l'instruction LOOP qui necessite l'emploi de CX comme compteur. A chaque tour de boucle, CX est automatiquement decremente. Si, apres decrementation, CX est nul, on sort de la boucle. ATTENTION : si CX est nul au premier tour, il est decremente. sa valeur devient 65535, et on peut attendre un bon moment la sortie de boucle ! MOV CX, NbDeTours 25 BouclePour: ... LOOP BouclePour ; corps de boucle On peut aussi utiliser LOOPE/LOOPZ qui realisent un melange de boucles POUR et TANT QUE en permettant de sortir quelque soit la valeur de CX si ZF vaut 1. LOOPE, par exemple, signie : boucler tant que l'egalite reste veriee et que CX est dierent de 0. De m^eme LOOPNE/LOOPNZ dans le cas contraire. L'exemple suivant permet de lire 8 chires au plus, et d'arr^eter la lecture a la frappe du RETURN. .DATA buf DB 8 DUP(0) .CODE MOV CX,8 MOV BX, OFFSET buf boucle: MOV AH,1 INT 21h ; lecture MOV [BX], AL ; rangement de l'octet lu INC BX CMP AL, 0Dh ; a t-on lu un RETURN ? LOOPNE boucle ; si NON, on continue jusqu' a ce que CX=0 12.2 Boucle TANT QUE Elles sont realisees a l'aide de sauts conditionnels. Le probleme est que la longueur occupee par le corps de la boucle ne peut depasser 127 octets. Il faut donc souvent coupler saut conditionnel et saut inconditionnel, ce qui revient a inverser logiquement la condition du TANT QUE : DebutTQ: ... var DB 1000 DUP(?) ... JE suite JMP DebutTQ suite: ... ; Si on a termin e, on sort de la boucle ; sinon, on revient au d ebut du Tant Que. 13 Traitement des cha^nes Le 8086 dispose d'instructions tres puissantes de traitement de cha^nes. 13.1 deplacements La famille des instructions LODS transfere un octet ou un mot de la memoire vers l'accumulateur. LODSB et LODSW modient SI en fonction de l'indicateur de direction DF. SI est incremente si DF=0 (CLD) SI est deecremente si DF=1 (STD) LODSB transfere un octet de DS:SI vers AL 26 LODSW transfere un mot de DS:SI vers AX CLD MOV SI,OFFSET chaine LODSB SI est incr ement e ... STD MOV SI, OFFSET cahine + LongueurChaine LODSW SI est d ecr ement e La famille STOS eectue le mouvement inverse, de l'accumulateur vers ES:DI. STOSB transfere le contenu de AL, tandis que STOSW transfere celui de AX. Les 2 programmes suivant ont le m^eme resultat. CLD MOV DI,0 MOV AL,'A' STOSB MOV AL, 'B' STOSB STD MOV DI,1 MOV AX,'AB' STOSW Voici l'exemple de la copie d'un tampon termine par le caractere nul. MOV AX, @DATA MOV DS, AX MOV ES, AX MOV SI, OFFSET buf1 MOV DI, OFFSET buf2 CLD boucle: LODSB ; r ecup ere DS:SI dans AL STOSB ; transf ere AL vers ES:DI CMP AL, 0 JNZ boucle fin: ... La famille des instructions MOVS (MOVSB, MOVSW) realise la m^eme chose que LODS suivi de STOS, a savoir le transfert de DS:SI vers ES:DI sans paser par AX. MOV AX,@DATA MOV DS,AX MOV ES,AX MOV SI,0 MOV DI,0 MOVSW ... ; transfert d'un mot de DS:SI vers ES:DI PREFIXE DE REPETITION : REP permet d'eliminer la construction d'une boucle pour transferer n octets ou n mots. Il sut au prealable de charger CX avec le nombre de valeurs a echanger entre les 2 positions memoire. MOV CX, TailleBuf CLD REP MOVSW 27 si CX vaut 0 au depart, l'instruction n'est pas executee ( et c'est heureux !). REP peut ^etre utilise avec l'ensemble des instructions de traitement de cha^ne, ainsi qu'avec SCAS et CMPS. REPE et REPNE sont aussi disponibles avec les signications respectives : repeter tant que egalite ou tant que pas egalite. SI et DI sont modies apres l'acces en memoire, ce qui fait qu'en n d'echange, on pointe sur une adresse posterieure (si on a fait CLD) au dernier element de la cha^ne. Si on a tranfere des mots, on pointe sur une adresse posterieure de 2 positions, les adresses etant toujours comptees en octet. 13.2 Analyse de cha^ne 13.2.1 SCAS eectue un balayage de la memoire pour chercher la presence ou l'absence d'un octet ou la valeur d'un mot. SCASB compare la valeur de l'octet dans AL avec celui situe en ES:DI; DI est modie selon la valeur de DF. Avec SCASW , c'est le contenu de AX qui est recherche. Exemple: recherche du caractere 'a' dans un texte termine par l'ASCII nul .DATA texte DB 'texte d''essai',0 dim EQU ($-texte) .CODE MOV AX, @DATA MOV DS, AX MOV ES, AX MOV DI, OFFSET texte ; DI pointe sur le d ebut du texte MOV AL, 'a' MOV CX, dim ; CX contient le nombre de caract eres a balayer. CLD ; balayage dans l'ordre direct. REPNE SCASB JE trouve JMP PasTrouve trouve : DEC DI ; on pointe maintenant sur 'a' 13.2.2 CMPS Permet de comparer directement 2 cha^nes. CMPSB compare l'octet en DS:SI avec celui en ES:DI et modie SI et DI simultanement selon DF. CMPSW agit de m^eme au niveau de mots. MOV SI, OFFSET tab1 MOV AX, SEG tab1 MOV DS, AX MOV DI, OFFSET tab2 MOV AX, SEG tab2 MOV ES, AX MOV CX, longueur CLD REPE CMPSW 28 JNE different .... different: DEC SI DEC SI DEC DI DEC DI ; on pointe sur les 2 el ements diff erents. 14 Sous-programmes 14.1 principe L'appel d'un sous-programme se fait par CALL label de sous-programme. Soit un programme implante a l'adresse 1000 et une procedure a l'adresse 1100. 1000 1002 1004 1007 1009 MOV AL,1 MOV BL,3 CALL SP MOV AL,2 INT 21h ---> 1100 | 1102 -----------1104 <------------1106 |-----1108 SHL ADD AND ADD RET AL, 1 AL,BL AL,7 AL,'0' Le sous-programme contient l'instruction RET qui permet de revenir au programme appelant. Lors du CALL, IP recoit la valeur 1100, adresse de la prochaine instruction a executer, tandis que l'adresse de retour 1007 est empilee. Sur le RET, le sommet de pile de valeur 1007 est depile, et son contenu est range dans IP. On trouvera dans les listings des exemples de programmes et sous-programmes. Le sous-programme ou procedure se declare donc : nomproc PROC .. .. RET nomproc ENDP La directive ENDP(End of Procedure) s'applique toujours a un label associe a la directive PROC. Le debut du programme principal correspond a l'etiquette associee a la directive END qui cl^ot le texte source a compiler. S'il n'y en a pas, c'est par la premiere instruction suivant le .CODE que l'execution demarre. 14.2 Passage des parametres Il existe deux techniques : par les registres ou par la pile. 14.2.1 par registres Avant l'appel, on charge les registres avec les valeurs des parametres. Ceci, a condition qu'ils ne soient pas trop nombreux, et qu'ils soient tous scalaires. Si l'on a aaire a des tableaux ou des structures, il faut manipuler l'adresse des objets. Avant le retour, la procedure appelee doit a son tour ranger ses resultats dans les registres. Ce mecanisme doit ^etre rigoureusement documente dans le programmelui-m^eme, sous forme de commentaires. On doit savoir quels sont les registres manipules, ce qu'ils representent en entree, en sortie, et quels sont ceux qui ont ete modies par le code. ( cf l'exemple ROUTINE.ASM) 29 14.2.2 par la pile On utilise a cet eet une structure, c'est a dire l'equivalent d'un enregistrement (RECORD). La syntaxe de declaration en est : nom STRUC champ1 type valeur champ2 type valeur ... nom ENDS Avant l'appel, les parametres sont empiles par une succession de PUSH. Lors du CALL, l'adresse de retour est rangee dans la pile. Elle est composee des deux registres CS et IP. On trouve donc dans la pile : IP CS par4 par3 par2 par1 <- SP <- BP L'acces a la pile se fait a partir de SP. Il vaut mieux ne pas modier la structure de la pile en cours d'execution du sous-programme, aussi on ne la depile pas. Mais on accede et on modie les valeurs qu'elle contient en utilisant des indirections avec BP. Il faut se souvenir ici que la pile est logee en haut de la memoire et que ses adresses croissent a l'inverse des adresses de la memoire. L'adresse du sommet est inferieure a celle de sa base ! Pour la manipuler comme on en a l'habitude et la \voir" conformement au schema ci-dessus, on a l'habitude d'intervertir les reperes que sont BP et SP avec la sequence : PUSH BP pour sauvegarder la valeur du registre MOV BP,SP BP contient la valeur de SP (adresses basses), ce qui nous permet par la suite d' ecrire des expressions avec [BP+depl] ... On doit egalement se souvenir que les adresses sont comptees en octet, alors que la pile stocke des mots. Les adresses vont donc de 2 en 2. L'adresse de par1 devient [BP+2], en adressage indirect, celle de par2 devient [BP+4], etc ... L'instruction RET depile en n d'execution l'adresse de retour. L'instruction RET n permet de d epiler, outre l'adresse de retour les n/2 parametres qui la precede. L'exemple suivant illustre ce qui vient d'^etre dit: TOTO PROC NEAR parametres STRUC par1 DW ? par2 DB ? par3 DB ? ; ces deux parametres tiennent sur le meme mot dans la pile par4 DW ? parametres ENDS params EQU [BP-par1] sub SP,2 ; on elimine l'adresse de retour de la zone d'adressage push BP mov BP,SP 30 ... mov AX, params.par1 mov BL, params.par2 mul BL ... POP bp ADD SP,2 RET 6 ; les parametres occupent 3 mots sur la pile TOTO ENDP dans cet exemple, les parametres ont ete depiles avant retour. Pour recuperer des resultats, il convient de sauver leur valeur dans des registres au prealable. 15 Programmes multi-modules Il est possible de faire de la compilation separee en assembleur. Le principal probleme qui se pose est le partage des donnees et du code entre plusieurs modules. Un exemple de realisation, propose en 3.1.3, illustre ce qui suit. On distingue le probleme du partage des donnees separement de celui du code. 15.1 Partage des donnees Les donnees, que ce soit en import ou en export, sont declarees avec la directive et associees a leur type, dans tous les modules ou on les utilise. Cette declaration regle uniquement le probleme de l'import-export. La declaration de reservation de place en memoire se fait ensuite dans le module a qui l'on attribue le r^ole de createur de cette donnee. GLOBAL ;Module du programme principal ... .DATA GLOBAL var1:WORD, var2:BYTE ; var1 est d efini pour l'usage d'un autre module var1 DW ? ; son implantation est d ecid ee ici .CODE GLOBAL P1 : NEAR, P2 : FAR ; La proc edure P1, d eclar ee "proche", n ec essite ; un d eplacement au sein du segment ; Pour P2, on a besoin de CS:IP pour acc eder ; a un autre segment ... MOV [var1],BX MOV AL,[var2] ... CALL P1 CALL P2 END ------------------------------------; Module de P1 .DATA GLOBAL var2:BYTE ; var2 est d eclar ee ici et sera utilis ee dans var2 DB ? ; le programme principal .CODE GLOBAL P1 ; cette d eclaration premet l'export de P1 P1 PROC NEAR ; D eclaration de P1 dans le segment de code courant ... 31 RET P1 ENDP END 15.2 partage du code Le principe est identique : une procedure importee est declaree GLOBAL. La dimension du pointeur qui permettra de l'atteindre est associee a cette declaration : NEAR si elle est situee dans le segment de code courant, FAR si elle est implantee dans un autre segment. A l'export, on rapelle le partage par GLOBAL. Le type du pointeur est associe a la declaration proprement dite qui se fait avec la directive PROC. Ce type doit ^etre compatible avec toutes les procedures qui vont l'importer. Nous n'ecrivons que de petits modules qui tiennent tous dans un m^eme segment. Par consequent, la declaration sera toujours NEAR. 16 Commandes de TASM 16.1 compilation la commande de compilation est : TASM [options] NomDeFichier Si on utilise * comme nom de chiers, tous les chiers d'extension .ASM sont compiles. L'option /zi permet de prendre en compte les donnees qui seront utilisees par TURBO-DEBUGEUR. 16.2 edition des liens On utilise la commande LINK. L'option /v permet l'utulisation de TURBODEBUGEUR. La commande s'applique a l'ensemble des chiers objets (d'extension .OBJ) qui compose le logiciel. On a deux solutions pour pr esenter ces arguments sur la ligne de commande { LINK /v a+b+c permet de lier les modules-objet contenus dans les chiers a.obj, b.obj et c.obj (un m^eme chier peut contenir plusieurs modules-objet). { LINK /v @f permet de lier les modules-objet contenus dans le chier f. Ce dernier est un chier de texte qui contient une liste de type : a + b + . . . + z. On utilise un tel chier en indirection des lors que le nombre de chiers composant est eleve. 17 Problemes courants Les erreurs les plus frequemment rencontrees sont : { l'oubli de revenir au DOS { l'oubli du RET dans une procedure. Le code continue de se derouler. { le fait que les operandes soient stockes a l'envers en memoire. la valeur 4BA7h stockee en memoire correspond a la valeur A74Bh d'une variable. { l'abscence du dimensionnement de la pile. { l'eacement de registres vitaux par une procedure. 32 { des erreurs de sens de sauts conditionnels. JA, JB, JAE et JBE traitent des donnees non signees. JG,JL, JGE et JLE traitent des donnees signees. le E traite l'egalite; ne pas confondre JA et JAE. Bien dierencier aussi JC et JNC (problemes de logique) { boucles : valeur de CX; veiller a ne pas avoir CX nul en debut de boucle. { oubli de retour en arriere sur les cha^nes avec REP. { indicateur de direction inverse { oubli de preparer les segments de cha^ne (ES) { operations arithmetiques avec retenue. Penser a eacer CF avec CLC. { attention a la dierence entre compte d'octets et compte de mots. { confusion valeur/adresse supposons que la variable var de valeur 1234h soit implantee a l'adresse 1000h. MOV MOV MOV MOV MOV BX, OFFSET var AX, [BX] AX, [var] [var], 5678h AX, var charge 1000h dans BX charge 1234h dans AX charge aussi 1234h dans AX charge 5678h dans AX 33 S.I.O. Travaux pratiques page 34 INSTRUCTIONS DU 8086 Documentation de travaux pratiques Lorsque la taille des arguments n’est pas indiquée, c’est que l’instruction accepte des arguments sur 8 ou 16 bits, à condition qu’ils soient de la même taille. Lorsqu’un des arguments peut être de plusieurs types, ces différents formats sont regroupés entre accolades. Exemple: {r+m} signifie registre ou mémoire. Lecture des instructions: Action sur les indicateurs: Les pages suivantes présentent le jeu d’instructions du 8086. Chaque instruction a le format suivant: Les trois actions possibles d’une instruction sur les indicateurs sont: • ?: on ne peut rien dire sur l’état de l’indicateur après l’instruction. • *: l’indicateur sera modifié par l’instruction, et cette modification nous renseignera sur le déroulement de l’instruction. • 0,1: valeur de l’indicateur après l’instruction. nom de l’instruction ADC Addition avec retenue: les deux opérandes et la retenue sont additionnés, et le résultat est placé dans le premier opérande. action Format: • ADC r,* format de l’appel • ADC m,{i+r} O ? D I T S ? Z ? A * P ? C * action sur les indicateurs Format des opérandes: Les opérandes peuvent être des types suivants: • r: registre (r8 registre 8 bits, r16 registre 16 bits). • m: mémoire. • i: valeur immédiate. • label: étiquette. • segreg: registre de segment (DS,ES,CS,SS). • ptr 16:16: adresse sous la forme segment:déplacement. Les indicateurs: Chacun d’eux joue un rôle particulier: • O: overflow. Mis à 1 si une opération provoque un dépassement de capacité. • D: direction. Fixe le sens dans lequel seront effectuées les opérations de traitement de chaînes de caractères. STD le met à 1, CLD à 0. • I: interruption. Mis à 1, il autorise les interruptions. S’il vaut 0, il les empêche. • T: trap. Mis à 1, il force le processeur à fonctionner pas à pas. • S: signe. Prend la valeur du bit de poids fort de l’accumulateur après un calcul. • Z: zéro. Mis à 1 si le résultat d’un calcul (i.e. le contenu de l’accumulateur) vaut 0. • A: retenue auxiliaire. Mis à 1 si un calcul en BCD non compacté produit une retenue. • P: parité. Mis à 1 si les 4 bits de poids faible du résultat contiennent un nombre pair de 1. • C: retenue (carry). Mis à 1 si un calcul produit une retenue. La virgule sépare les arguments lorsqu’il y en a deux. L’étoile ‘*’ remplace r,m ou i. Instructions du 8086 S.I.O. Travaux pratiques page 35 AAA Documentation de travaux pratiques AAS Ajustement ASCII après addition: corrige le contenu de AL après une addition de deux nombres en BCD non compacté, pour le mettre au format BCD non compacté. O ? D I T S ? Z ? A * P ? Ajustement ASCII de AL après soustraction: corrige le contenu de AL après une addition de deux nombres exprimés en BCD non compacté, pour le mettre au format BCD non compacté. O ? C * D I T S ? Z ? A * P ? C * ADC AAD Ajustement ASCII avant division: prépare le dividende ou le diviseur pour effectuer une division entre deux nombres exprimés en BCD non compacté. O ? D I T S * Z * A ? P * C ? Addition avec retenue: les deux opérandes et la retenue sont additionnés, et le résultat est placé dans le premier opérande. Format: • ADC r,* • ADC m,{i+r} O * D I T S * Z * A * P * C * AAM Ajustement ASCII après multiplication: corrige le contenu de AX pour le mettre au format BCD non compacté. O ? D I T S * Z * A ? P * C ? ADD Addition: les deux opérandes sont ajoutés et le résultat est placé dans le premier opérande. Format: le même que pour ADC. O * Instructions du 8086 D I T S * Z * A * P * C * S.I.O. Travaux pratiques page 36 AND Documentation de travaux pratiques CLI ET logique: Un ET logique est appliqué à chaque bit des opérandes, le résultat est placé dans le premier opérande. Format: • AND r,* • AND m,r O 0 D I T S * Z * A ? P * C 0 Mise à zéro de l’indicateur d’interruption. CMC Inverse l’indicateur de retenue. CMP Compare les deux opérandes en soustrayant le deuxième opérande au premier. Celui-ci n’est pas modifié, mais les indicateurs peuvent être modifiés Format: • CMP {r+m},* • CMP m,{i+r} CALL Appel de procédure. Les indicateurs ne sont pas modifiés. Format: • CALL label • CALL m16 • CALL r16 O * D I T S * Z * A * P * C * CMPS,CMPSB,CMPSW CBW Conversion d’octet en mot: transforme l’octet signé présent dans AL en un mot dans AX en recopiant dans tous les bits de AH le bit de poids fort de AL. CLC Compare des chaînes de caractères: compare le contenu de DS:SI à celui de ES:SI, arme les indicateurs en fonction du résultat de la comparaison, puis incrémente (si CLD a été exécuté) ou décrémente (si STD a été exécuté) SI et DI. Ces instructions peuvent être préfixées par REP et ses variantes. Format: • CMPSB (comparaison d’octets) et CMPSW (comparaison de mots) n’ont pas de paramètres. • Pour CMPS: m,m Mise à zéro de l’indicateur de retenue. O * CLD Mise à zéro de l’indicateur de direction (manipulation de chaînes). Instructions du 8086 D I T S * Z * A * P * C * S.I.O. Travaux pratiques page 37 DAA Documentation de travaux pratiques DIV Ajustement décimal de AL après addition: s’utilise après ADD pour recadrer le résultat de l’addition de deux nombres BCD au format BCD compact (un octet contient deux chiffres décimaux, chacun codé sur quatre bits). O ? D I T S * Z * A * P * C * Division non signée: effectue la division du contenu de l’accumulateur par la valeur de l’argument.Si l’argument est sur 8 bits, AL est le dividende, le quotient est placé dans AL et le reste dans AH, si l’argument est sur 16 bits, AX est le dividende, le quotient est placé dans AX et le reste dans DX. Format: • DIV {m+r} O ? D I T S ? Z ? A ? P ? C ? DAS Ajustement décimal de AL après soustraction: voir DAA. O ? D I T S * Z * A * P * C * HLT Suspend l’exécution du programme et place le processeur dans l’état balte. Le processeur ne repartira que par reset ou prise en compte d’une interruption.Dans ce dernier cas, on retrouve les contenus de CS et IP. DEC Décrémente l’argument de 1. Format: • DEC {r+m} O * D I T IDIV Division signée: voir DIV. S * Z * A * P * O ? C * Instructions du 8086 D I T S ? Z ? A ? P ? C ? S.I.O. Travaux pratiques page 38 IMUL Documentation de travaux pratiques INT,INTO Multiplication signée: multiplie le contenu de l’accumulateur par celui de l’opérande.Si celui-ci est sur 8 bits, AL est multiplié et le résultat est placé dans AX, s’il est sur 16 bits, AX est multiplié et le résultat se trouve dans DX:AX (Poids forts dans DX). Format: • IMUL {m+r} O * D I T S ? Z ? A ? P ? Appel d’interruption: INTO est un appel conditionnel qui ne sera effectif que si l’indicateur O vaut 1. Les indicateurs T et S sont mis à zéro. Format: • INT[O] i8 IRET C * Retour d’interruption. Dépile le registre des indicateurs. IN Jcondition Lecture de données sur un périphérique: transfère un octet ou un mot depuis le périphérique repéré par le deuxième opérande dans l’accumulateur. Format: • IN {AL,AX},i8 • IN {AL,AX},DX O * D I T S ? Z ? A ? P ? C * P * C INC Incrémente l’argument de un (voir DEC). O * D I T S * Z * A * Saut si la condition est vérifiée. Les conditions valides sont composées des lettres suivantes: • A: above (au dessus) • B: below (en dessous) • C: carry (retenue) • E: equal (égal, pair) • G: greater (plus grand) • L: lesser (plus petit) • N: not (non) • O: overflow (dépassement de capacité, impair) • P: parity (parité) • S: signed (signé) • Z: zero Les conditions acceptées sont les suivantes: JA,JAE,JB,JBE,JC,JE,JG,JGE,JL,JLE,JNA,JNAE,JNB,JNBE,JNC,JNE,JNG ,JNGE,JNL,JNLE,JO,JP,JPE,JS,JZ,JNO,JNP,JPO,JNS,JNZ. Il existe encore une autre condition : JCXZ qui effectue le branchement si CX vaut 0. L et G sont utilisés pour comparer des entiers signés, A et B pour des valeurs non signées. Les indicateurs ne sont pas modifiés. Instructions du 8086 S.I.O. Travaux pratiques page 39 Format: • Jcondition r128.r128 est une étiquette ou une valeur correspondant à un déplacement dans le segment de code courant d’au plus 128 octets en amont ou 127 octets en aval.Il est possible d’augmenter la longueur du saut en plaçant la directive JUMPS (annulée par NOJUMPS) dans le texte source avant l’instruction de saut. JMP Documentation de travaux pratiques LOCK Valide le préfixe de signal de verrouillage. Les indicateurs ne sont pas modifiés. LODS,LODSB,LODSW Charge un caractère dans l’accumulateur: charge dans AL (donnée sur 8 bits) ou AX (donnée sur 16 bits) la valeur pointée par DS:SI. LODS peut être préfixée par REP, ce qui a peu d’intérêt. Les indicateurs ne sont pas modifiés. Format: • LODSB et LODSW n’ont pas d’arguments. • LODS m Saut inconditionnel. Les indicateurs ne sont pas modifiés. Format: • JMP r128 • JMP r • JMP m • JMP ptr 16:16 LOOP, LOOPcondition LAHF Boucle: décrémente CX; si le résultat est différent de zéro, opère un branchement à l’adresse spécifiée en argument (voir Jcondition pour les formats). LOOPcondition effectue le branchement tant que la condition est vérifiée et que CX est différent de zéro. Les seules conditions valides sont LOOPE (ou LOOPZ), vrai quand l’indicateur Z est à un, et sa négation LOOPNE (ou LOOPNZ). Les indicateurs ne sont pas modifiés. Charge les indicateurs dans AH. Les indicateurs ne sont pas modifiés. LEA Charge une valeur de déplacement d’adresse: calcul l’adresse (offset) du second opérande et la place dans le premier. Les indicateurs ne sont pas modifiés. LDS,LES Charge un pointeur: Le premier mot (OFFSET) adressé par le deuxième opérande est placé dans le premier opérande, le second (SEGMENT) est placé dans DS (LDS) ou ES (LES). Les indicateurs ne sont pas modifiés. MOV Copie de données: recopie dans le premier opérande la valeur représentée par le deuxième opérande. Les indicateurs ne sont pas modifiés. Format: • MOV r,* • MOV m,{r+i} • MOV segreg,{r+m} • MOV {r+m},segreg Instructions du 8086 S.I.O. Travaux pratiques page 40 MOVS,MOVSB,MOVSW NOT Copie de données entre chaînes: copie l’octet(MOVSB) ou le mot (MOVSW) repéré par DS:SI dans ES:DI puis incrémente (CLD) ou décrémente (STD) SI et DI. Cette instruction peut être préfixée par REP. Les indicateurs ne sont pas modifiés. Format: • MOVSB et MOVSW n’ont pas de paramètres. • MOVS: m,m MUL Multiplication non signée: voir IMUL. O * D I T Documentation de travaux pratiques S ? Z ? A ? P ? Négation logique: l’opérande est remplacé par son complément à un. Les indicateurs ne sont pas modifiés. Format: • NOT {r+m} OR Ou logique: effectue un ou logique sur chaque bit des opérandes et place le résultat dans le premier opérande. Format: • OR {r+m},{imm+r} • OR r,m O 0 C * NEG D I T S * Z * A ? P * C 0 OUT Négation par complément à deux: l’opérande est remplacé par son complément à deux. L’indicateur de retenue est mis à un, sauf si l’opérande vaut 0, auquel cas l’indicateur de retenue est mis à 0. Format: • NEG {r+m} O * D I T S * NOP Pas d’opération. Les indicateurs ne sont pas modifiés. Z * A * P * C * Ecriture sur un périphérique: transfère une donnée depuis le premier opérande vers le périphérique repéré par le deuxième opérande. Les indicateurs ne sont pas modifiés. Format: • OUT {imm+DX},{AL+AX} POP Dépiler un mot: prend la valeur située au sommet de la pile et la place dans l’opérande, puis incrémente SP de 2. Les indicateurs ne sont pas modifiés. Format: • POP {r+m} • POP DS, ES ou SS Instructions du 8086 S.I.O. Travaux pratiques page 41 POPF Documentation de travaux pratiques REP,REPE,REPZ,REPNE,REPNZ Dépile le registre d’indicateurs: prend la valeur située en sommet de pile et la place dans le registre d’indicateurs. Tous les indicateurs sont susceptibles d’être modifiés. PUSH Empile l’opérande: décrémente SP de 2, puis place la valeur en sommet de pile. Les indicateurs ne sont pas modifiés. Format: • PUSH {r+m} Répétition d’opérations de manipulations de chaînes. Ces instructions sont des préfixes permettant la répétition des instructions de chaînes. REP décrémente CX puis répète l’instruction si CX est différent de zéro. REPE (=REPZ) et REPNE (=REPNZ) ne préfixent que les instructions des familles SCAS et CMPS; REPE (répéter tant que égal) arrête l’itération si l’indicateur Z vaut 0 (détection d’une inégalité), REPNE (répéter tant que non égal) est la condition opposée. L’indicateur Z peut être modifié. RET PUSHF Empile le registre des indicateurs, qui ne sont pas modifiés. RCL,RCR,ROL,ROR Rotation d’un octet ou d’un mot d’une ou CL positions. RCL: rotation vers la gauche en tenant compte de la retenue. A chaque étape de la rotation, la retenue est placée dans le bit de poids faible du premier opérande, le bit de poids fort de cet opérande est placé dans la retenue. ROL: rotation vers la gauche sans tenir compte de la retenue. A chaque étape de la rotation, la retenue prend la valeur du bit de poids fort du premier opérande avant la rotation. RCR et ROR sont les rotations vers la droite correspondantes. C et O peuvent être modifiés. Format: • {RCL+RCR+ROL+ROR} {r+m},{1+CL} Retour d’une procédure: IP et CS (retour long) sont dépilés. Si RET est suivi d’une valeur sur 16 bits, elle représente le nombre d’octets à enlever de la pile avant d’effectuer le retour de procédure (paramètres d’entrée de la procédure). Les indicateurs ne sont pas modifiés. SAHF Sauvegarde AH dans le registre des indicateurs (seulement les indicateurs S,Z,A,P,C). AH doit contenir SZ*A*P*C dans cet ordre. Instructions du 8086 S.I.O. Travaux pratiques page 42 SAL,SAR,SHL,SHR SCAS,SCASB,SCASW Instructions de décalage. SAL (=SHL) décale l’opérande vers la gauche de 1 ou CL bits. A chaque étape du décalage, le bit de poids fort du premier opérande est placé dans l’indicateur de retenue, le bit de poids faible est mis à 0. SHR est le décalage vers la droite symétrique de SAL. SAR ne modifie pas le bit de poids fort (décalage vers la droite des nombres signés). Format: voir RCL,RCR O * D Documentation de travaux pratiques I T S * Z * A ? P * C * Comparaison de [chaînes de] caractères. Compare le contenu de ES:DI à celui de l’accumulateur, modifie les indicateurs en conséquence, puis incrémente (si CLD a été exécuté) ou décrémente (STD) DI. S’utilise généralement préfixée par REPE ou REPNE. Format: voir MOVS. O * D I T S * Z * A * P * C * STC Met à un l’indicateur de retenue. STD Met à un l’indicateur de direction. SBB STI Soustraction avec retenue: le deuxième opérande et la retenue éventuelle sont soustraits du premier opérande et le résultat est placé dans le premier opérande. Format: voir ADC O * D I T S * Z * A * P * C * Met à un l’indicateur d’autorisation d’interruptions. STOS,STOSB,STOSW Range le contenu de l’accumulateur dans une chaîne: copie le contenu de l’accumulateur dans ES:DI, puis incrémente (CLD) ou décrémente (STD) DI. STOSB copie le contenu de AL, STOSW celui de AX. STOS utilise AL ou AX, selon la taille de l’opérande. Les indicateurs ne sont pas modifiés. Format: • STOSB et STOSW n’ont pas d’arguments. • Pour STOS: m. Instructions du 8086 S.I.O. Travaux pratiques page 43 SUB Documentation de travaux pratiques XLAT,XLATB Soustraction: soustrait le deuxième opérande au premier et place le résultat dans le premier. Format: voir ADC. O * D I T S * Z * A * P * C * Table de correspondance: avant d’appeler XLAT, AL doit contenir un indice de tableau, BX l’adresse de base du tableau. Au retour, AL contient la valeur de la case correspondante du tableau. Les indicateurs ne sont pas modifiés. Format: • XLAT m8 • XLATB XOR TEST Comparaison: même action que AND, mais le résultat n’est pas gardé. Format: voir AND. O 0 D I T S * Z * A ? P * Ou exclusif. Format: voir OR. O 0 C 0 WAIT Arrêt du processeur jusqu’à ce que la broche BUSY# soit inactive. Cette broche est gérée par le coprocesseur. Les indicateurs ne sont pas modifiés. XCHG Echange les contenus des deux opérandes. Les indicateurs ne sont pas modifiés. Format: • XCHG {r+m},r • XCHG r,{r+m} Instructions du 8086 D I T S * Z * A ? P * C 0 S.I.O. Travaux pratiques Documentation de travaux pratiques PRINCIPALES INTERRUPTIONS DU DOS/BIOS S.I.O. Travaux pratiques page 45 Documentation de travaux pratiques Interruption 10h, fonction 00h Interruption 10h, fonction 02h Fixer le mode vidéo. Positionnement du curseur. Entrée: Entrée: AH=2 BH=Page écran. DH=Ligne de l’écran. DL=Colonne de l’écran. Sortie: Aucune. Sortie: AH=0 AL=mode vidéo. 0 40*25 caractères noir et blanc. (carte couleur). 1 40*25 caractères couleur. (carte couleur). 2 80*25 caractères noir et blanc (carte couleur) 3 80*25 caractères couleur (carte couleur) 4 320*200 points, 4 couleurs. 5 320*200 points, 4couleurs 6 640*200 points, 4 couleurs. 7 Carte monochrome. 8 160*200, 16 couleurs. (PC junior) 9 320*200, 4 couleurs. (PC junior) 0Ah 640*200, 4couleurs (PC junior) 0Dh 320*200, 16 couleurs. 0Eh 640*200, 16 couleurs. 0Fh 640,350, monochrome. 10h 640*350, 16 couleurs. 11h 640*480, 2 couleurs. 12h 640*480, 16 couleurs. 13h 640*480, 256 couleurs. Interruption 10h, fonction 03h Lecture de la position du curseur. Entrée: AH=3 BH=Numéro de la page écran. Sortie: DH=Ligne du curseur. DL=Colonne du curseur. CH=Ligne de départ du curseur. CL=Ligne de fin du curseur. Aucune. Interruption 10h, fonction 01h Interruption 10h, fonction 05h Définir l’apparence du curseur. Sélection de la page d’écran. Entrée: AH=1 CH=Ligne de départ du curseur (0-13). CL=Ligne de fin du curseur (0-7). Entrée: AH=5 AL=Numéro de la page écran. Sortie: Aucune. Sortie: Aucune. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 46 Documentation de travaux pratiques Interruption 10h, fonction 06h Interruption 10h, fonction 09h Faire défiler des lignes de texte vers le haut. Ecriture d’un caractère et de son attribut. Entrée: Entrée: AH=9 BH=Page écran. CX=Nombre d’écritures successives du caractère. AL=Code ASCII du caractère. BL=Attribut. Sortie: Aucune. Sortie: AH=6 AL= Nombre de lignes du décalage. CH=Ligne écran du coin supérieur gauche. CL=Colonne écran du coin supérieur gauche. DH=Ligne écran du coin inférieur droit. DL=Colonne écran du coin inférieur droit. BH=Couleur des lignes vides. Aucune. Interruption 10h, fonction 0Ah Ecriture d’un caractère. Interruption 10h, fonction 07h Entrée: AH=0Ah BH=Page écran. CX=Nombre d’écritures successives du caractère. AL=Code ASCII du caractère. Sortie: Aucune. Faire défiler des lignes de texte vers le bas. Entrée: AH=7 Mêmes paramètres que pour l’interruption 10h fonction 6. Sortie: Aucune. Remarque: Ne modifie pas la position du curseur. Interruption 10h, fonction 08h Interruption 10h, fonction 0Bh, service 0 Lecture d’un caractère et de son attribut. Sélection des couleurs de cadre et de fond. Entrée: AH=8 BH=Numéro de la page écran. Entrée: AH=0Bh BH=0 BL=Couleur de cadre et de fond. Sortie: AL=Code ASCII du caractère. AH=Couleur. Sortie: Aucune. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 47 Documentation de travaux pratiques Interruption 10h, fonction 0Bh, service 01h Interruption 10h, fonction 0Fh Sélection de la palette de couleurs. Lecture du mode vidéo. Entrée: Entrée: AH=0Fh Sortie: AL=Mode vidéo (voir fonction 0 de l’interruption 10h). AH=Nombre de caractères par ligne. BH=Numéro de la page écran. Sortie: AH=0Bh BH=1 BL=Numéro de la palette. Aucune. Interruption 10h, fonction 0Ch Allumer un point. Entrée: Sortie: AH=0Ch DX=Ligne. CX=Colonne. AL=Couleur. BH=Page écran. Interruption 10h, fonction 13h Sortie d’une chaîne de caractères. Entrée: AH=13h AL=Mode de sortie(0-3): 0=Attribut dans BL, conserver position du curseur. 1=Attribut dans BL, bouger curseur. 2=Attribut dans buffer, conserver position du curseur. 3=Attribut dans buffer, bouger curseur. BL=Attribut des caractères. CX=Longueur de la chaîne. DH=Ligne. DL=Colonne. BH=Page écran. ES:BP=Adresse du buffer. Sortie: Aucune. Aucune. Remarque: Si le bit 7 de AL vaut 1, un OU exclusif est appliqué entre la nouvelle et l’ancienne couleur. Interruption 10h, fonction 0Dh Lire un point. Entrée: Sortie: AH=0Dh DX=Ligne. CX=Colonne. BH=Page écran. Remarque: Les codes de commande sont interprétés comme tels. AL=Couleur. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 48 Documentation de travaux pratiques Interruption 11h Interruption 21h, fonction 01h Déterminer la configuration. Entrée de caractères avec sortie. Entrée: Aucune. Entrée: AH=1 Sortie: AX contient le codage de la configuration: Pour XT: Bit 0=1 s’il y a un lecteur de disquettes. Bit 2 et 3=Mémoire RAM sur la carte mère: 00=16 Ko 01=32 Ko 02=48 Ko 03=64 Ko Bit 4 et 5=Mode vidéo: 01=40*25 couleur. 10=80*25 couleur. 11=80*25 monochrome. Bit 6 et 7=Nombre de lecteurs de disquettes (00=1 lecteur). Bit 8=0 si DMA présent. Bit 9-11=Nombre de RS232 présentes. Bit 12=1 si joystick connecté. Bit 14-15=Nombre d’imprimantes. Pour AT: Bit 1=1 si coprocesseur présent. Les bits 2,3,8,12 et 13 sont inutilisés.Les autres gardent la même signification. Sortie: AL=Caractère lu. Remarque: Si un code étendu est entré, AL contient 0, il faut rappeler l’interruption pour connaître le caractère entré. Interruption 21h, fonction 02h Sortie d’un caractère. Entrée: AH=2 DL=Code ASCII du caractère. Sortie: Aucune. Remarque: Interprète les codes de commande. Interruption 21h, fonction 06h Entrée/sortie directe de caractère. Interruption 12h Déterminer la taille mémoire. Entrée: Aucune. Sortie: AX=Taille mémoire en Ko. Entrée: AH=6 DL=Si FFh alors lire un caractère, sinon l’écrire. Sortie: Si DL=FFh alors: ZF=1 pas de caractère à lire. ZF=0 le caractère est dans AL. Si DL=FFh, pas de sortie. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 49 Documentation de travaux pratiques Interruption 21h, fonction 07h Interruption 21h, fonction 0Ah Entrée de caractère sans sortie. Entrée d’une chaîne de caractères. Entrée: AH=7 Entrée: AH=0Ah DS:DX=Adresse du buffer. Sortie: AL=Caractère lu. Sortie: Aucune. Remarque: Permet la saisie des codes étendus, mais pas de CTRL-C. Remarque: Permet la saisie des codes étendus et CTRL-C. Interruption 21h, fonction 08h Interruption 21h, fonction 2Ah Entrée de caractère sans sortie. Lire la date. Entrée: AH=8 Entrée: AH=2Ah Sortie: AL=Caractère lu. Sortie: AL=Jour de la semaine (dimanche=0). CX=Année (1980=0). DH=Mois. DL=Jour. Remarque: Permet la saisie des codes étendus, et de CTRL-C. Interruption 21h, fonction 09h Interruption 21h, fonction 2Bh Sortie d’une chaîne de caractères. Fixer la date. Entrée: AH=9 DS:DX=Adresse de la chaîne. Entrée: Sortie: Aucune. AH=2Bh CX=Année(1980=0). DH=Mois. DL=Jour. Sortie: AL=FFh, date erronée. Remarque: La chaîne doit être terminée par un $. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 50 Documentation de travaux pratiques Interruption 21h, fonction 2Ch Interruption 21h, fonction 39h Lire l’heure. Créer un sous-répertoire. Entrée: AH=2Ch Entrée: Sortie: CH=Heure. CL=Minutes. DH=Secondes. DL=Centièmes de seconde. AH=39h DS:DX=Adresse du nom du sous-répertoire à créer (chaîne ASCII terminée par 0-ASCIIZ). Sortie: CF=0 création réussie. CF=1 AX=3 Chemin non trouvé. AX=5 Accès refusé. Interruption 21h, fonction 2Dh Fixer l’heure. Entrée: Sortie: AH=2Dh CX et DX au même format que pour l’interruption ci-dessus. AL=FFh si heure erronée. Interruption 21h, fonction 30h Interruption 21h, fonction 3Ah Supprimer sous-répertoire. Entrée: AH=3Ah DS:DX=Adresse du nom du sous-répertoire(ASCIIZ). Sortie: CF=0 Suppression effectuée. CF=1 Mêmes codes d’erreur que ci-dessus. Déterminer le numéro de version du DOS. Entrée: AH=30h Sortie: AL=Version. AH=Sous-version. Interruption 21h, fonction 3Bh Changer de répertoire. Interruption 21h, fonction 31h Entrée: AH=3Bh DS:DX=Adresse du nom du sous-répertoire(ASCIIZ). Sortie: CF=0 changement réussi. CF=1, alors AX=3 (chemin non trouvé). Terminer le programme mais laisser résident. Entrée: AH=31h AL=Code de fin. DX=Nombre de paragraphes à réserver (1 paragraphe=16 octets). Sortie: Aucune. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 51 Documentation de travaux pratiques Interruption 21h, fonction 3Ch Interruption 21h, fonction 3Eh Créer fichier. Fermer fichier. Entrée: AH=3Ch CX=Attribut du fichier: Bit 0=1 Lecture seulement. Bit 1=1 Fichier caché. Bit 2=1 Fichier système. DS:DX=Adresse du nom du fichier(ASCIIZ). Entrée: AH=3Eh BX=Handle du fichier. Sortie: CF=0 tout s’est bien passé. CF=1 alors AX=6 (handle interdit ou fichier non ouvert). CF=0 création réussie; AX=Handle du fichier. CF=1 problème: AX=3 Chemin non trouvé. AX=4 Trop de fichiers ouverts. AX=5 Accès refusé. Interruption 21h, fonction 3Fh Sortie: Interruption 21h, fonction 3Dh Lire fichier. Entrée: AH=3Fh BX=Handle du fichier (Handle du clavier=0). CX=Nombre d’octets à lire. DS:DX=Adresse du buffer. Sortie: CF=0 tout va bien, AX=nombre d’octets lus. CF=1 AX=5 accès interdit. AX=6 handle non autorisé ou fichier non ouvert. Ouvrir fichier. Entrée: Sortie: AH=3Dh AL=Mode d’accès.Principalement: Bits 0-2: 000=Lecture seulement. 001=Ecriture seulement. 010=Lecture/écriture. DS:DX=Adresse du nom du fichier. Interruption 21h, fonction 40h Ecrire dans un fichier. CF=0 ouverture réussie; AX=Handle du fichier. CF=1 problème. AX=2 fichier non trouvé. AX=3 chemin non trouvé. AX=4 trop de fichiers ouverts. AX=5 accès refusé. Entrée: AH=40h BX=Handle du fichier (Handle de l’écran=1). CX=Nombre d’octets à écrire. DS:DX=Adresse du buffer. Sortie: CF=0 tout s’est bien passé, AX=nombre d’octets écrits. CF=1 AX=5 accès refusé. AX=6 handle non autorisé ou fichier non ouvert. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 52 Documentation de travaux pratiques Interruption 21h, fonction 41h Interruption 21h, fonction 43h, sous-fonction 0 Détruire un fichier. Lire attribut de fichier. Entrée: AH=41h DS:DX=Adresse du nom du fichier (ASCIIZ). Entrée: AH=43h AL=0 DS:DX=Adresse du nom du fichier. Sortie: CF=0 fichier supprimé. CF=1 erreur: AX=2 fichier non trouvé. AX=5 accès refusé. Sortie: CF=0 alors CX=Attribut du fichier: Bit 0=1 Lecture seulement. Bit 1=1 Fichier caché. Bit 2=1 Fichier système. Bit 5=1 Modifié depuis le dernier archivage. CF=1 erreur: AX=1 Code de fonction inconnu. AX=2 Fichier non trouvé. AX=3 Chemin non trouvé. Interruption 21h, fonction 42h Déplacer le pointeur de fichier. Entrée: Sortie: AH=42h AL=code de la distance: 0=Par rapport au début du fichier. 1=Par rapport à la position actuelle du pointeur. 2=Par rapport à la fin du fichier. BX=Handle. CX=Mot de poids faible de la distance. DX=Mot de poids fort de la distance. CF=0 tout s’est bien passé: DX:AX=Nouvelle position du pointeur de fichier. (par rapport au début du fichier) CF=1 erreur: AX=1 distance incorrecte. AX=6 handle non autorisé ou fichier non ouvert. Interruption 21h, fonction 43h, sous-fonction 1 Fixer attribut de fichier. Entrée: AH=43h AL=1 CX=Attribut du fichier (voir ci-dessus, de plus les bit 3 et 4 doivent être mis à 0). DS:DX=Adresse du nom du fichier. Sortie: CF=0 tout s’est bien passé. CF=1 erreur: AX=1 code de fonction inconnu. AX=2 fichier non trouvé. AX=3 chemin non trouvé. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 53 Documentation de travaux pratiques Interruption 21h, fonction 47h Interruption 21h, fonction 4Ah Déterminer répertoire courant. Modifier la taille d’une zone mémoire. Entrée: AH=47h DL=Désignation du périphérique. DS:SI=Adresse du buffer (prévoir 64 octets au maximum). Entrée: AH=4Ah BX=Nouvelle taille de la zone en paragraphes. ES:00=Adresse de la zone mémoire. Sortie: CF=0 tout s’est bien passé, DS:SI contient la spécification du chemin. CF=1 erreur, AX=15 (périphérique inconnu). Sortie: CF=0 tout s’est bien passé. CF=1 erreur: AX=7 bloc de contrôle de la mémoire détruit. AX=8 pas assez de mémoire. BX=Nombre de paragraphes encore disponibles. Interruption 21h, fonction 48h Réserver mémoire RAM. Entrée: Sortie: Interruption 21h, fonction 4Ch AH=48h BX=Nombre de paragraphes. Terminer un programme. CF=0 réservation réussie, AX:0=adresse de la zone. CF=1 alors: AX=7 bloc de contrôle de la mémoire détruit. AX=8 pas assez de mémoire. BX=Nombre de paragraphes encore disponibles. Entrée: AH=4Ch AL=Code de fin. Sortie: Aucune. Interruption 21h, fonction 4Dh Interruption 21h, fonction 49h Déterminer code de fin. Libérer mémoire RAM. Entrée: Sortie: AH=49h ES:00=Adresse de la zone à libérer (la taille est connue du DOS). CF=0 Mémoire libérée. CF=1 erreur: AX=7 bloc de contrôle de la mémoire détruit. AX=9 cette zone n’avait pas été allouée par la fonction 48h. Entrée: AH=4Dh Sortie: AH=0 fin normale. AH=1 arrêt par CONTROL-C ou BREAK. AH=2 arrêt par erreur d’accès à un périphérique. AH=3 arrêt par appel à l’interruption 21h,fonction 31h, ou à l’interruption 27h. AL=Code de fin. Principales interruptions du DOS/BIOS S.I.O. Travaux pratiques page 54 Documentation de travaux pratiques Interruption 21h, fonction 4Eh Interruption 21h, fonction 62h Rechercher première entrée du répertoire. Déterminer adresse de PSP du programme en cours. Entrée: Entrée: AH=62h Sortie: BX:0=Adresse du PSP. Sortie: AH=4Eh CX=Attribut du fichier. DS:DX=Adresse du nom du fichier (peut contenir des jokers). CF=0 tout s’est bien passé, la DTA a été mise à jour. CF=1 erreur: AX=2 chemin non trouvé. AX=18 pas de fichier correspondant au schéma. Interruption 21h, fonction 4Fh Rechercher prochaine entrée du répertoire. Entrée: AH=4Fh Sortie: CF=0 tout s’est bien passé, la DTA a été mise à jour. CF=1 erreur AX=18 (pas de fichier correspondant au schéma). Interruption 21h, fonction 5Ah Créer fichier temporaire. Entrée: AH=5Ah CX=Attribut du fichier. DS:DX=Adresse du nom du répertoire. Sortie: CF=0 Tout s’est bien passé, alors: AX=Handle. CX=Atribut du fichier. DS:DX=Adresse du nom du fichier complet. CF=1 erreur: AX=3 chemin non trouvé. AX=5 Accès refusé. Remarque: Le fichier n’est pas détruit à la fin du programme. Principales interruptions du DOS/BIOS
Documents pareils
Cours 8 : Mémoire et Registres
Q8.17 : Comment le microprocesseur 8086 sait-il que la mémoire contient une donnée
plutôt qu’une instruction?
Q8.18 : Les énoncés suivants sont-ils vrais ou faux :
Énoncé
V/F
Chaque mode d’adressa...