Académique Documents
Professionnel Documents
Culture Documents
Objectives
Les objectifs de ce chapitre sont:
- Montrer comment des nombres non signés de 8-bits et 16-bits sont additionnés avec les
P80x86.
- Convertir des données vers l’une de ces formes: ASCII, BCD Paqueté, et BCD Non Paqueté.
- Expliquer l’effet des instructions arithmétiques non signées sur le registre FLAG.
- Montrer comment additionner, soustraire, multiplier et diviser des nombres non signés avec les
instructions: ADD/ADC, SUB/SBB, MUL, et DIV respectivement.
- Expliquer les instructions arithmétiques en ASCII et BCD: DAA, DAS, AAA, AAS, AAM, et AAD.
- Coder avec les instructions logiques AND, OR, XOR, SHR, SHL, ROR/ROL/RCR/RCL et CMP.
- Expliquer comment les nombres signés de 8-bits et 16-bits sont représentés avec les P80x86.
- Convertir un nombre signé en complément à 2.
- Montrer comment additionner, soustraire, multiplier et diviser des nombres signés avec les
instructions: ADD, SUB, IMUL, et IDIV respectivement, et comment ces arithmétiques affectent le
registre FLAG.
- Éviter les erreurs de dépassement avec la notion de données au signe étendu avec les
instructions CBW et CWD.
- Les instructions de décalage arithmétique SAR et SAL et les instructions de décalage logiques,
SHR, SHL.
- L’instruction de comparaison CMP en arithmétique signé et son effet sur le registre flag RF.
- Décrire le bit direction flag DF dans les instructions de chaînes de caractères et l’utilisation de
CLD et STD pour contrôler ce bit.
- Expliquer comment manipuler les chaînes de caractères, et décrire l’opération de l’instruction
préfixe REP.
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
3/53
Un opérande dest. peut être un registre ou dans la mémoire. Un opérande source peut être un
registre, dans la mémoire, ou une valeur immédiate. Les opérations de mémoire à mémoire non
permises dans le langage assembleur du 80x86. L’instruction ADD peut changer les indicateurs
ZF, SF, AF, CF ou PF du registre FLAG. Le OF concerne les opérations signées.
DEC CX
JNZ ENCORE
MOV SUM, AX
Résultat stocké dans un
mot mémoire dans le DS
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
5/53
ORG 0010H
DATA2 DQ 3FCD4FA23B8DH
ORG 0020H
SUM DQ ? ; = 945D09387874H
.CODE
MAIN PROC FAR
MOV AX, @DATA
MOV DS, AX
CLC ; reset la retenue
MOV, AL, 3FH, MOV, BH, 23H, SUB AL, BH 0011 1111 - 0010 0011
+ 1101 1101 (Cà2 de 0010 0011)
--------------
1 0001 1100 CF 0, ZF = 0, PF = 0, SF = 0 (bit D7 est 0)
Si CF = 0, le résultat est positive. Sinon il est négative. Dans ce cas l’opérande destination contient le
Cà2 du résultat. Normalement, ce résultat est laissé tel quel, sinon on peut utiliser les instructions
NOT et INC pour le changer si on veut par un programme:
Cette instruction concerne les nombres « multi-mots » qui prend en compte la retenue ’’empreint =
borrow’’ de l’opérande (mot) précédent. Si CF=0, SBB est équivalente a SUB. Si CF=1, SBB
soustrait 1 du résultat.
DATA_A DD 62562FAh
DATA_B DD 412963Bh
RESULTAT DD ?
… … …
MOV AX, WORD PTR DATA_A ; AX = 62FAh Note: la directive PTR demande a l’assembleur
; d’assigner a DATA_A le type WORD même si elle est déclarée
DD
SUB AX, WORD PTR DATA_B ; SUB 963Bh de (AX = 62FAh)
MOV WORD PTR RESULTAT, AX ; stocker le résultat
Le résultat:
MOV AL, DATA3 ; charger l’un des opérandes (ici dans la mémoire DS) dans AX
MUL DATA2 ; le multiplier par le 2eme opérande (dans la mémoire DS)
MOV RES_MUL, AX ; le LSB du résultat (dans AX) dans la mémoire DS (RES_MUL)
MOV RES_MUL+2, DX ; le MSB du résultat (dans DX) dans la mémoire DS (RES_MUL+2)
- Mot x Octet: De même les registres AX (mot LSB) et DX (mot MSB) sont utilisés pour stocker les résultat.
Mais AL contient l’opérande en octet et AH est mis a zéro.
DATA5 DB 0B6H
DATA6 DW 12C3H
RES_MUL2 DW 2 DUP(?)
; ------------------ du segment de code -----------------------------------------------------------------------------------------------------
MOV AL, DATA5 ; charger l’un des opérandes (ici dans la mémoire DS) dans AL
SUB AH, AH ; AH est mis a zéro
MUL DATA6 ; Multiplier le 1er par le 2eme opérande (les 2 se trouvant la mémoire DS)
MOV BX, OFFSET RES_MUL2 ; BX pointe sur la location mémoire de RES_MUL2
MOV [BX], AX ; le LSB du résultat (dans AX) dans la location mémoire pointée par
BX
MOV [BX]+2, DX ; le MSB du résultat (dans DX) dans la location mémoire pointée par
BX+2
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
11/53
Deux cas « exception » ou la CPU ne peut effectuer une division: division par « 0 » ou si le
quotient est plus large que la taille du registre. Un signal d’interruption est activé et le PC
affiche un message d’erreur.
- Octet / Octet: Num. AL; 0 HL Denom. ne peut être une valeur immédiate
Après DIV, Quotient AL; Reste AH.
DATA7 DB 95
DATA8 DB 10
QOUT1 DB ?
ROUT1 DB ?
MOV AL, DATA7 ; le numérateur (ici dans la mémoire DS) toujours dans AL
SUB AH, AH ; AH toujours mis à 0
DIV 10 ; Adressage immédiat n’est pas permis message d’ERREUR
- Adressage direct:
MOV AL, DATA7 ; le numérateur (ici dans la mémoire DS) toujours dans AL
SUB AH, AH ; AH toujours mis a 0
DIV DATA8 ; AX / DATA8
MOV QOUT1, AL ; Quotient = AL (09)
MOV ROUT1, AH ; Reste = AH (05)
- Adressage registre:
- Mot / Mot: (Num. AX; 0 DX. Denom. Reg./Mem.) Après DIV : (Quot. AX; Reste DX)
QOUT2 DW ?
ROUT2 DW ?
- Mot / Octet: (Num. AX; Denom. Reg./Mem.) Après DIV : (Quot. AL; Reste AH)
MOV AX, 2050 ; Num. AX
MOV CL, 100 ; Denom. CL
DIV CL ; AX / CL
MOV QOUT1, AL ; Quotient = AL (20)
MOV ROUT1, AH ; Reste = AH (50)
- DoubleMot / Mot: (Num. [DX,AX]; Denom. Reg./Mem.) Après DIV : (Quot. AX; Reste DX)
DATA9 DD 105432
DATA10 DW 10000
QOUT, ROUT DW ?
MOV AX, WORD PTR DATA9 ; mot LSB du Num. AX Noter WORD PTR sinon ERREUR
MOV DX, WORD PTR DATA9 + 2 ; mot MSB du Num. DX Noter WORD PTR DATA9 + 2 DX
Instruction XOR: XOR destination, source (Destination = Reg. ou Mem.Source = Reg., Mem., ou donnée immédiate)
X Y X xor Y
MOV DH, 54H
XOR DH , 78H ; DH XOR 78h DH (2Ch). 0 0 0
0 1 1
Avec l’instruction XOR, si les bits sont égaux, le bit résultant est 0 et vice versa.
Avec XOR, seuls les indicateurs ZF, SF et PF sont affectés et (CF, OF) 0. 1 0 1
Application: L’instruction XOR est utilisée pour: 1 1 0
- Mettre à 0 le contenu d’un registre (XOR AL, AL), le résultat, toujours 00h, AL
- Comparer deux registres si leur contenus sont égaux (XOR AX, CX).
Si c’est les cas ZF 1 et le résultat est sauvegardé dans la destination (0000
AX)
- Basculer (toggle) ou inverser un ou plusieurs bits (0 1 ou 1 0):
Les instructions de décalage logiques affectent les indicateurs OF, SF, PF et ZF.
Les opérandes à décaler peuvent être dans un registre ou dans la mémoire mais jamais en mode immédiat.
DATA1 DB 9AH
FOIS EQU 3
MOV CL, FOIS
SHR AL , CL ; AL est décalé à droite CL (3) fois : CF = 0, ensuite 1 et enfin 0
Compare CF ZF
L’instruction CMP affecte les indicateurs AF, OF, SF, PF, CF et ZF Opérandes
mais seuls CF et ZF sont utilisés.
Dest. > Src. 0 0
L’opérande destination peut être dans un registre ou dans une mémoire. Dest. = Src. 0 1
L’opérande source peut être dans un registre, dans une mémoire, ou en mode immédiat.
Les opérandes (destination et source) ne changent pas. Dest. < Src. 1 0
DATA1 DW 235FH
…
MOV BX, 7888H ; 7888Hh BX
MOV CX, 9FFFH
CMP BX, CX ; BX < CX CF=1 JNC est exécutée PASSE
JNC PASSE ; Note: les contenus de (BX, et CX) ne changent pas après CMP
ADD BX, 4000H
PASSE: ADD CX, DATA1 ; mais CF est toujours vérifié pour (< ou >). Pour (=) on utilise ZF.
TEMP DB ?
…
MOV AL, TEMP ; TEMP AL
CMP AL, 99 ; TEMP = 99?. Avec (SUB AL, 99), la même chose mais 0 AL
JZ PROCHAIN ; Si ZF=1 (TEMP=99), Saute a PROCHAIN:
INC BX ; Sinon incrémente BX
PROCHAIN: HLT ; Arrêt du programme
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
19/53
ROR RCR
MSB LSB CF MSB LSB CF
ROL RCL
CF MSB LSB CF MSB LSB
CLC ; CF = 0
MOV BX, 0C7E5H ; 1100011111100101B BX
MOV CL, 2 ; 0110001111110010 BX et CF = 1
RCR BX, CL ; 1111000111111001 BX et CF = 0
STC ; CF = 1
MOV BH, 72H ; 01110010B BH
MOV CL, 2 ; 11100101B BH et CF = 0
RCL BL, CL ; 11001010B BX et CF = 1
TITLE prog3_5.asm: Exemple sur ROL, Trouver le nombre de ‘1’ dans un mot
PAGE 60, 132
.MODEL SMALL
.STACK 64
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.DATA
DATA1 DW 5F97H
COMPTE DB ?
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX, @DATA
ENCORE: MOV AX, WORD PTR [BX] ; Déplacer les prochains 2 nombres ASCII vers AX
AND AX, 0F0FH ; Masquer (Enlever) les 3s d’ASCII (les 3 MSB bits) la conversion
MOV WORD PTR [DI], AX ; sauvegarder le résultat (le BCD NonPaqueté)
ADD BX, 2 ; pointe vers le prochain nombre ASCII
ADD DI, 2 ; pointe vers le prochain nombre en BCD NonPaqueté
LOOP ENCORE ; encore une fois si ce n’est pas fini jusqu’a ce que CL = 0
Ou encore:
.MODEL SMALL
.STACK 64
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.DATA
ORG 0010H
VAL_ASC DB ’47’
VAL_BCD DB ? ; le directive DB met 34 dans “0010” et 37 dans “0011”
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX, @DATA
MOV AX, WORD PTR VAL_ASC ; le contenu de VAL_ASC dans AX: (37)AH, 34AL
AND AX, 0F0FH ; Masquer 3 pour avoir le DCB NonPaqueté
XCHG AH, AL ; Échanger AH et AL
MOV CL, 4 ; 04 CL to décaler 4 fois
SHL AH, CL ; décaler a gauche AH pour obtenir 40HAH
OR AL, AH ; pour obtenir le BCD paqueté équivalent a ’47’
MOV VAL_BCD, AL ; sauvegarder le résultat dans la case mémoire
VAL_BCD
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN
.MODEL SMALL
.STACK 64
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.DATA
V_BCD DB 29H ; le directive DB met 29H dans l’offset “0000”
V_ASC DB ?
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX, @DATA
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN
Additionner deux nombres BCD (Paqueté) ne donne pas forcement un nombre BCD, car
nous risquons d’avoir les digits A, B, … F. Pour y remédier le programmeur doit corriger en
ajoutant 6 (0110). Les P-CISC sont menés d’une instruction spécifique, comme DAA
d’Intel.
DAA travaille uniquement avec le registre AL. Ses actions sont:
- Si après ADD ou ADC, le Quartet (Nibble) LSB est >9 ou si AF = 1 ajouter 0110 au
Quartet LSB. Sinon l’instruction DAA laisse le résultat tel qu’il est après ADD/ADC.
- Si le Quartet (Nibble) MSB est >9 ou si CF = 1 ajouter 0110 au Quartet MSB.
Exemples:
47H + 25H (LSB >9) , 29H + 18H (AF = 1), 42H + 85H (MSB >9) , 93H + 81H (CF = 1) DAA
DATA1 DB 47H
DATA2 DB 25H
DATA3 DB ?
.DATA
DATA1_ASC DB ‘0649147816’
ORG 0010H
DATA2_ASC DB ‘0072687188’
ORG 0020H
DATA1_BCD DB 5 DUP(?) ; 5 car chaque octet est l’équivalent de 2 ASCII 5 mots
ORG 0028H
DATA2_BCD DB 5 DUP(?)
ORG 0030H
DATA3_BCD DB 5 DUP(?)
ORG 0040H
DATA3_ASC DB 10 DUP(?) ; 10 car chaque caractère ASCII (et il y’a 10) est un octet
;---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX, @DATA Suite
MOV DS, AX
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
29/53
MOV BX, OFFSET DATA1_ASC ; BX pointe sur les données de la première série ASCII
MOV DI, OFFSET DATA1_BCD ; DI les données de la première série convertie en
BCD
MOV CX, 10 ; CX contient le nombre d’octets équivalents aux 10
ASCII
CALL CONV_BCDP ; Procédure de conversion d’ASCII en BCP Paqueté
MOV BX, OFFSET DATA2_ASC ; BX pointe sur les données de la deuxième série ASCII
MOV DI, OFFSET DATA2_ BCD ; DI les données de la deuxième série convertie en
BCD
MOV CX, 10 ; CX contient le nombre d’octets équivalents aux 10
ASCII
CALL CONV_BCDP ; Procédure de conversion d’ASCII en BCP Paqueté
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h Suite
MAIN ENDP
END MAIN
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
30/53
CONV_ASC PROC
REPETER: MOV AL, [SI] ; SI les données en BCD
MOV AH, AL ; Dupliquer pour dépaqueter
AND AX, 0F00FH ; SI les résultats de l’addition en BCD
PUSH CX ; Sauvegarder le compteur
MOV CL, 04 ; pour décaler
SHR AH, CL ; décaler a droite de 4 fois pour obtenir le quartet MSB
OR AX, 3030H ; conversion vers ASCII en ajoutant les 3s
XCHG AH, AL ; permuter pour retrouver les codes ASCII
MOV [DI], AX ; sauvegarder la donnée ASCII
INC SI ; pointe sur la prochaine donnée BCD
INC DI, 2 ; pointe sur la prochaine donnée ASCII
POP CX ; retrouver le CX original du compteur
LOOP REPETER ; répéter jusqu’à ce que CX=0
RET
CONV_ASC ENDP
;-----------------------------------------------------------------------------------------------------------------------------------------------------------
De même que l’addition, soustraire deux nombres BCD (Paqueté) ne donne pas
forcement un nombre BCD, car nous risquons d’avoir les digits A, B, … F. Pour y
remédier le programmeur doit corriger en soustrayant 6 (0110). Les P-CISC sont
menés d’une instruction spécifique, comme DAS d’Intel.
De même que DAA, DAS travaille uniquement avec le registre AL. Ses actions
sont:
Exemple:
47H - 29H (AF = 1) DAS
Noter
l’utilisation du mode d’adressage « Base relatif : BX + depl.» pour permettre l’accès d’un
tableau a 3 dimension avec un seul registre pointeur BX. C’est l’avantage que procure ce
type de mode d’adressage.
La directive BYTE PTR est pour indiquer que les données pointées par BX sont des Octets et par
des Mots. Sans cette directive, le P prendra en considération deux bytes au lieu d’un.
Il est possible d’effectuer une addition et une soustraction en ASCII sans le besoin de masquer
les 3s (011), moyennant les instructions AAA et AAS qui utilisent également le registre AL.
Si l’addition est >9, AAA applique la correction en ajoutant 0110 et le bit extra CF AH
SUB AH, AH ; AH = 00
MOV AL, ‘5’ ; 35h AL
MOV BL, ‘7’ ; 37h BL
ADD AL, BL ; 35h + 37h 6Ch (dans AL)
AAA ; 6Ch 02h (dans AL) et CF=AH=1
OR AX, 3030h ; AX OR 3030H 3137h (code ASCII de ‘12’)
Remarque: la donnée a ajouter peut bien être en BCD NonPaqueté au lieu d’ASCII.
ASC_ADD PROC
CLC ; 0 CF
MOV CX, 10 ; compteur de boucle (10 octets)
MOV BX, 9 ; BX l’Octet LSB
ARRIERE: MOV AL, VAL_1[BX] ; Prendre le prochain octet de l’opérande 1
ADC AL, VAL_2[BX] ; Additionner le prochain octet de l’opérande 2
AAA ; Ajustant pour le rendre ASCII
MOV RES_1[BX], AL ; Sauvegarder la somme ASCII
DEC BX ; pointe sur le prochain octet ASCII
LOOP ARRIERE ; répéter jusqu’à ce que CX=0
RET
ASC_ADD ENDP
;---------------------------------------------------------------------------------------------------------------------------------------------------
; Cette procédure permet de convertir le BCD NonPaqueté vers ASCII
BCDNP_ASC PROC
MOV BX, OFFSET RES_1 ; BX Données BCD NP
MOV SI, OFFSET RES_2 ; SI Données ASCII
MOV CX, 5 ; compteur de boucle (5 mots)
ARRIERE2: MOV AX, WORD PTR[BX] ; Prendre les 2 prochains octets ASCII
OR AX, 3030H ; Insérer les 011s (3s) d’ASCII
MOV WORD PTR[BX], AX ; Sauvegarder la conversion en ASCII
ADD BX,2 ; Incrémenter le pointeur BCD NP
ADD SI,2 ; Incrémenter le pointeur ASCII
LOOP ARRIERE2 ; répéter jusqu’à ce que CX=0
RET
BCDNP_ASC ENDP
;---------------------------------------------------------------------------------------------------------------------------------------------------
BCDNP_ASC PROC
MOV BX, OFFSET RES_1 ; BX Données BCD NP
MOV SI, OFFSET RES_2 ; SI Données ASCII
MOV CX, 5 ; compteur de boucle (5 mots)
ARRIERE2: MOV AX, WORD PTR[BX] ; Prendre les 2 prochains octets ASCII
OR AX, 3030H ; Insérer les 011s (3s) d’ASCII
MOV WORD PTR[BX], AX ; Sauvegarder la conversion en ASCII
ADD BX,2 ; Incrémenter le pointeur BCD NP
ADD SI,2 ; Incrémenter le pointeur ASCII
LOOP ARRIERE2 ; répéter jusqu’à ce que CX=0
RET
BCDNP_ASC ENDP
CDSEG ENDS
;------------------------------------------------------------
END MAIN
Si 2 opérandes en BCD NonPaqueté sont a multiplier, AAM convertit le résultat en BCD NonPaqueté. La
conversion vers ASCII est du ressort de l’utilisateur en utilisant OR par exemple. De même pour la division
avec AAD.
Octet Signé
D7 D6 . . . . . D0
+127 0111 1111 Signe
Magnitude
+126 0111 1110
… …
+2 0000 0010 Nombres positifs
[ - 128 + 127 ]
+1 0000 0001
0 0000 0000
-1 1111 1111
-2 1111 1110
Nombres négatifs ‘Complément à 2’ des magnitudes de leurs équivalents positifs
… … - n = NOT (+ n) + 1
-127 1000 0001 Exemple: -32 NOT (+32d = 00100000b) + 1 11011111 + 1 11100000b
-128 1000 0000
Mot Signé
D15 D14 D8 D7 D6 . . . . . D0
+32767 0111 1111 1111 1111
+ Signe
+1 0000 0000 0000 0001 Magnitude
0 0000 0000 0000 0000
-1 1111 1111 1111 1111
-
-32768 1000 0000 0000 0000 [ - 32768 + 32767 ]
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
42/53
- Avec un P de 16 bits
+ 6E2Fh + (+ 13D4h) + 8203h mais le P donne –7DFD ?!?!? avec CF=0, SF=1 et OF = 1
OF = 1 si:
- Il existe une retenue de D6 à D7 (SF=1) mais pas de retenue a la sortie de D7 (CF = 0) dans
le cas d’opérations sur octets. Ou une retenue de D14 à D15 (SF=1) mais pas de retenue a
la sortie de D15 (CF = 0) dans le cas d’opérations sur des mots.
- Il y’a une retenue a la sortie de D7 (CF = 1) mais pas de retenue de D6 à D7 (SF=0) dans le
cas d’opérations sur octets. Ou d’une retenue a la sortie de D15 (CF = 1) mais pas de
retenue de D14 à D15 (SF=0) dans le cas d’opérations sur des mots.
En d’autres termes:
OF = CF XOR SF
Règle: si OF=1 le résultat est erroné Correction avec avec les instructions CBW, CWD
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
43/53
- Instruction CWD 15 0 15 0
A titre d’exercice on reprend l’exemple précédent avec DW pour DATA1 (+96F4h) et DATA2 (+70C!H),
DD pour RESLT, CWD au lieu de CBW, AX au lieu de AL, AX+DX au lieu de AX (addition multimot).
Note: C’est à l’utilisateur, et non pas le P, d’effectuer la correction dans les opérations non signées.
MOV AX, -9
MOV BL, 2 D7 D6 D0 CF
IDIV BL ; -9 / 2 FCh = - 4 (approximation vers le haut)
MOV AX, -9 SAR
SAR AX, 1 ; -9 /2 avec le décalage arithmétique FBh = - 5 (approximation vers le bas)
COMPARAISON DES NOMBRES SIGNÉS CMP dest., src avec JG, JGE, JL, JLE et JE
Avec les nombres non signés, les indicateurs CF et ZF sont utilisés avec l’instruction CMP pour la
vérification des conditions J . Alors qu’avec les nombres signés c’est les indicateurs OF, SF et ZF qui
sont utilisés.
DF (registre flag) Incrémentation (DF=0) Décrémentation (DF=1) du pointeur utilisé pour les opérations
CLD DF=0 STD DF=1
XLAT (translater) est une instruction pour accéder a des éléments d’une table de données
MOV AX,@DATA
MOV DS,AX ; Initialiser le segment de données
MOV ES,AX ; Initialiser le segment Extra
CLD ; DF=0 Auto-incrémentation des pointeurs SI et DI
MOV SI,OFFSET DATA_S ; Charger le pointeur source
MOV DI,OFFSET DATA_S ; Charger le pointeur destination
MOV CX, 20 ; Charger le compteur
REP MOVSB ; Déplacer les octets pointés par SI vers des locations pointés par DI et répéter
jusqu’a ; CX 0, sachant qu’a chaque itération SI et DI sont automatiquement incrémentés
MOV AH,4CH
INT 21H ; DOS
MAIN ENDP
END MAIN
TITLE PROG3_13.asm ; Stocker une données (CCh) dans 100 locations mémoire et tester leurs contenus
pour ; vérifier si la mémoire est défectueuse, auquel cas un message est affiché
PAGE 60,132
.MODEL SMALL
.STACK 64
.DATA
MESSAGE DB ‘ Mémoire défectueuse’
ESP_MEM DB 100 DUP(?)
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX ; Initialiser le segment de données
MOV ES,AX ; Initialiser le segment Extra
CLD ; DF=0 Auto-incrémentation des pointeurs SI et DI
MOV CX, 50 ; Charger le compteur avec 50 (50 mots = 100 octets)
MOV DI,OFFSET ESP_MEM ; Charger le pointeur destination
MOV AX, 0CCCCH ; le pattern qui servira de test
REP STOSW ; Placer AAAAH dans 50 locations mémoires pointées par DI (jusqu’à CX0)
; sachant qu’a chaque itération DI est automatiquement incrémenté
MOV SI,OFFSET ESP_MEM ; Charger le pointeur source
MOV CX, 100 ; Charger le compteur avec 100 (100 octets)
ENCORE: LODSB ; Charger de DS:SI vers AL (pas de REP)
XOR AL, AH ; Est ce que le pattern est est le même, sachant que dans AL et AH se trouve CCh
JNZ PASSE ; Sortir du programme si c’est différent mémoire défectueuse
LOOP ENCORE ; continue jusqu’a CX0
JMP SORTIR
PASSE: MOV DX, OFFSET MESSAGE ; Afficher un message sur écran
MOV AH,09H ; le message est ‘Mémoire défectueuse’
INT 21H ; DOS
SORTIR: HALT
MAIN ENDP
END MAIN
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
52/53
MOV AX,@DATA
MOV DS,AX ; Initialiser le segment de données
MOV ES,AX ; Initialiser le segment Extra
CLD ; DF=0 Auto-incrémentation des pointeurs SI et DI
MOV SI,OFFSET MOT_EXACT ; Charger le pointeur source
MOV DI,OFFSET MOT_TAPEE ; Charger le pointeur destination
MOV CX, 6 ; Charger le compteur avec 6 (6 lettres ou octets)
REPE CMPSB ; Répéter tant que les deux lettres sont égales ou jusqu’a C= 0. Si c’est différent le programme
; sort de cette instruction. A noter qu’a chaque itération SI et DI sont automatiquement
incrémentés.
JE PASSE ; Si ZF=1 afficher le message 1 (égalité)
MOV DX,OFFSET MESSAGE2 ; Si ZF=0 afficher le message 2 (différence)
JMP AFFICHAGE
MAIN ENDP
END MAIN
TITLE PROG3_14.asm ; Balayer une chaîne de caractère et Remplacer une lettre particulière par une autre
PAGE 60,132
.MODEL SMALL
.STACK 64
.DATA
CHAINE DB ‘Mr. Gones’ , ‘$’
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX ; Initialiser le segment de données
MOV ES,AX ; Initialiser le segment Extra
CLD ; DF=0 Auto-incrémentation des pointeurs SI et DI
MOV DI, OFFSET CHAINE ; Charger le pointeur destination ES:DI
MOV CX, 9 ; Charger le compteur avec 9 (la taille de la chaîne de caractères)
MOV AL, ‘G’ ; le caractère a scanner (balayer)
REPNE SCASB ; Répéter le balayage tant que les deux lettres ne sont pas égales ou jusqu’a C=
0. JNE PASSE ; Saut si ZF=0 afficher le message 1 (égalité)
DEC DI ; Décrémenter DI (a la lettre G) car entre autre DI s’est automatiquement
incrémenté
MOV BYTE PTR[DI], ‘J’ ; Remplacer ‘G’ par ‘J’
PASSE: MOV DX, OFFSET CHAINE
AFFICHAGE: MOV AH,09H ; le message correcte est affiche: ‘Mr. Jones’
INT 21H ; DOS
MAIN ENDP
END MAIN