Vous êtes sur la page 1sur 32

1/53

Chapitre 3 : Instructions Arithmétiques et Logiques,


nombres signés, chaînes et tables

Section 3.1: Addition et Soustraction en non signe


Section 3.2: Multiplication et Division en non signe
Section 3.3: Instructions logiques et quelques exemples

Section 3.4: Instructions ASCII et BCD


Section 3.5: Opérations au niveau bit dans le langage C
Section 3.6: Opérations arithmétiques non signées
Section 3.7: Instructions des chaînes et des tables de données

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


23/53

Section 3.4: Instructions ASCII et BCD


INSTRUCTIONS ASCII et BCD
Touche ASCII (en Binaire) BCD NonPaqueté
Note:
0 011 0000 0000 0000
1 011 0001 0000 0001
2 011 0010 0000 0010
3 011 0011 0000 0011 “89” en BCD NonPaqueté est:
4 011 0100 0000 0100 “0000 1000 0000 1001”
5 011 0101 0000 0101 Alors qu’en BCD Paqueté est:
6 011 0110 0000 0110
«  1000 1001».
7 011 0111 0000 0111
8 011 1000 0000 1000
9 011 1001 0000 1001

ASCII  BCD (NonPaqueté)


ASC DB ‘9562481273’ ; convertir 10 nombres ASCII en BCD NonPaqueté
ORG 0010H
NONPAQ DB 10 DUP (?)

MOV CX, 5 ; compteur de 5 mots  10 octets (nombres ASCII)
MOV BX, OFFSET ASC ; BX pointe vers les nombres en ASCII a convertir
MOV DI, OFFSET NONPAQ ; DI pointe vers les nombres en BCD NonPaqueté

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

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


24/53

Instructions ASCII et BCD


Note:
Les pointeurs BX et DI ont été utilisés pour pointer vers une matrice de données de dimension 2. Q’en
est-il si cette matrice est multidimensionnelle?
La solution est d’utiliser un seul pointeur et le mode d’adressage Base ou Index Relatif.
ASC DB ‘9562481273’ ; convertir 10 nombres ASCII en BCD NonPaqueté
ORG 0010H
NONPAQ DB 10 DUP (?)

MOV CX, 10 ; compteur de 10 octets puisque AL est utilisé
SUB BX, BX ; BX pointe vers les nombres en ASCII a convertir
ENCORE: MOV AL, ASC[BX] ; Déplacer vers AL le contenu de [BX + ASC].
; A la place de BX, les pointeurs BP/DI/SI peuvent être utilisés.
AND AL, 0FH ; Masquer le quartet (nibble) MSB
MOV NONPAQ[BX], AL ; Déplacer vers la case mémoire [BX + UNPAQ] le contenu de AL
INC BX ; pointe vers le prochain OCTET
LOOP ENCORE ; encore une fois si ce n’est pas fini jusqu’a ce que CL = 0

Ou encore:

MOV CX, 5 ; compteur de 5 octets puisque AX est utilisé


SUB BX, BX ; BX pointe vers les nombres en ASCII a convertir
ENCORE: MOV AX, WORD PTR ASC[BX] ; Déplacer vers AX les contenus de [BX + ASC] et [BX + ASC]+1.
; A la place de BX, les pointeurs BP/DI/SI peuvent être utilisés.
AND AX, 0F0FH ; Masquer les quartets (nibbles) MSB des 2 octets du mot
MOV WORD PTR UNPAQ[BX], AL ; Déplacer vers la case mémoire [BX + UNPAQ] le contenu de AX
ADD BX, 2 ; pointe vers le prochain MOT
LOOP ENCORE ; encore une fois si ce n’est pas fini jusqu’a ce que CL = 0
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
25/53

Instructions ASCII et BCD


ASCII  BCD (Paqueté) le passage par la conversion “ASCII  BCD NonPaqueté“ est nécessaire

TITLE prog3_6.asm: Convertir les touches ASCII ‘47’ en BCD Paqueté


PAGE 60, 132

.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, 34AL
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 40HAH
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

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


26/53

Instructions ASCII et BCD


BCD (Paqueté)  ASCII le passage par la conversion “ BCD Paqueté  BCD NonPaqueté“ est nécessaire

TITLE prog3_6b.asm: Convertir le nombre BCD Paqueté 29H en ASCII


PAGE 60, 132

.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 AL, V_BCD


MOV AH, AL ; 29HAH , 29HAL
AND AX, 0F00FH ; Masquer 9 de AH et 2 de AL
MOV CL, 4 ; 04  CL to décaler 4 fois
SHR AH, CL ; décaler a droite AH pour obtenir le BCD NonPaqueté
OR AX, 3030H ; Combiner avec 30H pour obtenir le code ASCII
XCHG AH, AL ; Échanger AH et AL
MOV V_ASC, AX ; sauvegarder le code ASCII dans la case mémoire V_ASC

;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


27/53

Instructions ASCII et BCD


ADDITION BCD ET CORRECTION

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
6h (0110b). 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 LS Nibble (Quartet) est >9 ou si AF = 1  ajouter 0110 au LS


Nibble (Quartet). Sinon l’instruction DAA laisse le résultat tel qu’il est après ADD/ADC.

- Si le MS Nibble (Quartet) est >9 ou si CF = 1  ajouter 0110 au MS Nibble Quartet.


Exemple:

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 ?

MOV AL, DATA1 ; 1er opérande BCDAL


MOV BL, DATA2 ; 2eme opérande BCDBL
ADD AL, BL ; Addition BCD
DAA ; Ajuster pour la correction BCD
MOV DATA3, AL ; Sauvegarder le résultat (72H) BCD

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


28/53

Instructions ASCII et BCD


Exemple:
Il s’agit d’écrire un programme, qui à partir de 2 ensembles de touches ASCII, tapées à partir
du clavier, permet de:
1. Les convertir du code ASCII vers BCD Paqueté.
2. Additionner les deux multi-mots en BCD Paqueté et sauvegarder le résultat.
3. Convertir ce résultat, en BCD paqueté, vers le code ASCII.
TITLE prog3_7.asm: ASCII   BCD Paqueté et Addition BCD Paqueté
PAGE 60, 132
.MODEL SMALL
.STACK 64
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.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
MOV DS, AX Suite
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
29/53

Instructions ASCII et BCD

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é

CALL ADD_BCD ; Procédure d’addition des opérandes BCP Paqueté

MOV SI, OFFSET DATA3_BCD ; SI  les résultats issus de la conversion en BCD


MOV DI, OFFSET DATA3_ASC ; DI  les résultats convertis en ASCII
MOV CX, 5 ; CX contient le nombre de MOTS (5) a convertir en ASCII
CALL CONV_ASC ; Procédure de conversion de BCD Paqueté en ASCII

;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN

Suite

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


30/53

Instructions ASCII et BCD


; Cette procédure convertit ASCII  BCD Paqueté
CONV_BCDP PROC
ENCORE: MOV AX, [BX] ; BX  données ASCII
XCHG AH, AL
AND AX, 0F0FH ; masque les 3s (MSB) d’ASCII
PUSH CX ; sauvegarder le compteur CX, puisqu’on l’utilisera
MOV CL, 4 ; pour décaler 4 fois
SHL AH, CL ; décaler 4 fois a gauche, pour être prêt au paquetage
OR AL, AH ; combinaison pour la conversion en BCD Paqueté
MOV [DI], AL ; DI  données BCD
ADD BX, 2 ; pointer au prochains 2 octets ASCII
INC DI ; pointer pour la prochaine donnée (mot) BCD
POP CX ; retrouver la valeur du compteur de boucle
LOOP ENCORE
RET correction
CONV_BCDP ENDP
;---------------------------------------------------------------------------------------------------------------------------------------------------

; Cette procédure additionne 2 opérandes multi-mots en BCD Paqueté


BCD_ADD PROC
MOV BX, OFFSET DATA1_BCD ; BX  les opérandes 1 (de la 1ere série converties en BCD)
MOV DI, OFFSET DATA2_BCD ; DI  les opérandes 2 (de la 2eme série converties en BCD)
MOV SI, OFFSET DATA3_BCD ; SI  les résultats de l’addition en BCD
MOV CX, 5 ; CX contient le nombre de mots (5) a additionner en BCD
CLC ; CF  0
ARRIERE: MOV AL, [BX]+4 ; obtenir les prochain octet de l’opérande 1
ADC AL, [DI]+4 ; additionner avec les prochain octet de l’opérande 2
DAA ; correction pour l’addition BCD
MOV [SI]+4, AL ; sauvegarder le résultat de l’addition BCD
DEC BX ; pointer sur le prochain octet de l’opérande 1
DEC DI ; pointer sur le prochain octet de l’opérande 2 Suite
DEC SI ; pointer sur le prochain octet de la somme

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


31/53

Instructions ASCII et BCD


LOOP ARRIERE
RET
BCD_ADD ENDP
;---------------------------------------------------------------------------------------------------------------------------------------------------
; Cette procédure convertit BCD Paqueté  ASCII

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
;-----------------------------------------------------------------------------------------------------------------------------------------------------------

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


32/53

Instructions ASCII et BCD


SOUSTRACTION BCD ET CORRECTION
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:

- Si après SUB ou SBB, le LS Quartet (Nibble) est >9 ou si AF = 1  soustraire


0110 au LS Quartet. Sinon l’instruction DAS laisse le résultat tel qu’il est après
SUB/SBB.

- Si le MS Quartet (Nibble) est >9 ou si CF = 1  soustraire 0110 au Quartet MS.

Exemple:
correction
47H - 29H (AF = 1) DAS

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


33/53

Instructions ASCII et BCD


SOUSTRACTION BCD ET CORRECTION
BUDGET DT 87965141012 ; La Directive DT (Ten ou 10 Octets) pour représenter les
DEPENSES DT 31610640392 ; nombres BCD, de 0 à 1020-1. Pas besoin de spécifier H.
BALANCE DT ? ; BALANCE = BUDGET - DEPENSES

MOV CX, 10 ; Compteur = 10


MOV BX, 00 ; pointeur BX  0
CLC ; CF = 0 pour la 1ere itération
REPETER: MOV AL, BYTE PTR BUDGET[BX] ; saisir un octet du BUDGET
SBB AL, BYTE PTR DEPENSES[BX] ; saisir un octet du DEPENSES
DAS ; Corriger le résultat pour la soustraction BCD
correction MOV BYTE PTR BALANCE[BX], AL ; Sauvegarder dans BALANCE
INC BX ; Incrémenter pour le prochain Octet
LOOP REPETER ; Continuer la boucle jusqu’à CX = 0

Noter

l’utilisation du mode d’adressage « Base relatif : BX + depl.» pour permettre l’accès d’un
tableau à 3 dimensions 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.
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
34/53

Instructions ASCII et BCD


ADDITION ET SOUSTRACTION ASCII
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.
MOV AL, ‘5’ ; 35h  AL
ADD AL, ‘2’ ; 35h + 32h  67h (dans AL)
AAA ; 67h  07h
OR AL, 30h ; AL OR 30H  37h (code ASCII de ‘7’)

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 à ajouter peut bien être en BCD NonPaqueté au lieu d’ASCII.

MOV AX, 105H ; 0105h  AX (BCD NonPaqueté de 15)


MOV CL, 06 ; 06H  CL
SUB AL, CL ; FFH  AL (5-6 = -1)
AAS ; FFh – 06h  09h et AH –1  AH  0009H  AX

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


35/53

Instructions ASCII et BCD


ADDITION ET SOUSTRACTION ASCII: Exemple
TITLE prog3_8.asm: Additionner des nombres ASCII
PAGE 60, 132
.MODEL SMALL
.STACK 64
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.DATA
VAL_1 DB ‘0649147816’
ORG 0010H
VAL_2 DB ‘0072687188’
ORG 0020H
RES_1 DB 10 DUP(?) ; réserver 10 cases mémoire pour le résultat RES_1
ORG 0030H
RES_2 DB 10 DUP(?) ; réserver 10 cases mémoire pour le résultat RES_2
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX, @DATA
MOV DS, AX
CALL ASC_ADD ; Appeler la procédure d’addition des nombres ASCII

CALL BCDNP_ASC ; Appeler la procédure de conversion vers ASCII


;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN Suite
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
36/53

Instructions ASCII et BCD


;---------------------------------------------------------------------------------------------------------------------------------------------------
; Cette procédure permet d’additionner des nombres ASCII et prend le résultat en BCD NonPaqueté

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[SI], AX ; Sauvegarder la conversion en ASCII
ADD BX,2 ; Incrémenter le pointeur BCD NP
ADD SI,2 ; Incrémenter le pointeur ASCII
correction LOOP ARRIERE2 ; répéter jusqu’à ce que CX=0
RET
BCDNP_ASC ENDP
;---------------------------------------------------------------------------------------------------------------------------------------------------

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


37/53

Instructions ASCII et BCD


TITLE prog3_8b.asm: Additionner des nombres ASCII en Segment Complet (Ancien style de l’assembleur)
PAGE 60, 132
STSEG SEGMENT
DB 64 DUP(?)
STSEG ENDS
;---------------------------------------------------------
DTSEG SEGMENT
VAL_1 DB ‘0649147816’
ORG 0010H
VAL_2 DB ‘0072687188’
ORG 0020H
RES_1 DB 10 DUP(?) ; réserver 10 cases mémoire pour le résultat RES_1
ORG 0030H
RES_2 DB 10 DUP(?) ; réserver 10 cases mémoire pour le résultat RES_2
DTSEG ENDS .CODE
;---------------------------------------------------------
CDSEG SEGMENT
MAIN PROC FAR
ASSUME CS:CDSEG, DS:DTSEG, SS:STSEG
MOV AX, DTSEG
MOV DS, AX
CALL ASC_ADD ; Appeler la procédure d’addition des nombres AS
CALL BCDNP_ASC ; Appeler la procédure de conversion vers ASCII
MOV AH, 4Ch
INT 21h
MAIN ENDP
; Cette procédure permet d’additionner des nombres ASCII et prend le résultat en BCD NonPaqueté
ASC_ADD PROC
CLC ; 0  CF
MOV CX, 10 ; compteur de boucle (10 octets)
MOV BX, 9 ; BX  l’Octet LSB

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


38/53

Instructions ASCII et BCD

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
CDSEG ENDS
;------------------------------------------------------------
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


39/53

Instructions ASCII et BCD


MULTIPLICATION ET DIVISION EN BCD NONPAQUETÉ
Les instructions AAM et AAD convertissent le résultat de la ‘X’ et de la ‘/’ en BCD NonPaqueté
Le manuel d’Intel parle de ASCII Ajust Multiplication et Division pour AAM et AAD. Mais en réalité, il
s’agit d’une correction pour les ‘X’ et ‘/’ en code BCD NonPaqueté.
Les instructions AAM et AAD travaillent seulement avec le registre AX.

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.
MOV AL, ‘7’ ; 37h  AL
AND AL, 0Fh ; 07h  AL en BCD NonPaqueté
MOV DL, ‘6’ ; 36h  DL
AND DL, 0Fh ; 06h  DL en BCD NonPaqueté
MUL DL ; AL x DL  AX (07 x 06 = 002Ah ou 42D)
AAM ; Correction: 0402  AX en BCD NonPaqueté (7x6=42)
OR AX, 3030h ; AX OR 3030H  3432h (code ASCII de ‘42’)

MOV AX, 3539 ; 3539h  AL. ASCII de 59


AND AX, 0F0Fh ; 0509h  (AH, AL) en BCD NonPaqueté
AAD ; Correction: 003Bh  AX (le HEX de 59D)
MOV BH, 08h ; Diviser par 8
DIV BH ; 3B/08  AL= 07 et AH = 03
OR AX, 3030h ; AL = 37H (quotient), AH = 33H (reste), les ASCII de Q et R

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


40/53

Section 3.5: Opérations Logiques (Niveau Bit) en C


L’avantage du langage C  opérations logiques: A B ~A A&B A|B A^B
- Donnée >> nombre de bits a décaler a droite 0 0 1 0 0 0
- Donnée << nombre de bits a décaler a gauche
0 1 1 0 1 1
/* prog3_9.c Reprends quelques exemples précédents en C */
#include <stdio.h> 1 0 0 0 1 1
main() 1 1 0 1 1 0
{
// Les données HEX en C sont définit en utilisant 0x
unsigned char data_1 = 0x35;
unsigned int data_2 = 0x504;unsigned int data_3 = 0xDA66;
unsigned char data_4= 0x54;unsigned char data_5=0x78;
unsigned char data_6=0x37;unsigned char data_7=0x09A;
unsigned char temp;unsigned int temp_2;
temp=data_1&0x0F; //ET
printf("\nMasque le quartet MSB de %X (hex) nous avons %X (hex)\n",data_1,temp);
temp_2=data_2|data_3; //OU
printf(« Le résultat de %X hex ORé avec %X hex est %X hex\n",data_2,data_3,temp_2);
temp= data_4^data_5; //XOR
printf(" Le résultat de %X hex ORé avec %X hex est %X hex\n",data_4,data_5,temp);
temp=~data_6; //INVERSE
printf(" Le résultat de %X hex inversé est %X hex\n",data_6,temp);
temp=data_7>>3; // DECALAGE DROITE
printf(« Quand %X hex est décalé a gauche 3 fois, nous avons %X hex\n",data_7,temp);
printf(" Quand %X hex est décalé a droite 3 fois, nous avons %X hex\n",0x7777,0x7777>>4);
temp=(0x6<<4); //DECALAGE GAUCHE
printf(" Quand %X hex est décalé a gauche %d fois, nous avons %X hex\n",0x6,4,temp);
}

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


41/53

Section 3.6: Opérations arithmétiques non signées

Températures  +15°C, 0 °C, -21°C  Nombres non signés

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

Opérations arithmétiques non signées


PROBLEME DU DEPASSEMENT dans l’arithmétique non signée  CBW, CWD
Exemples:

- Avec un P de 8 bits  (+60H) + (+46h) 


+96d + (+70d)  + 166d mais le P donne –90d ?!?!? avec CF=0, SF=1 et OF = 1

- 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

Opérations arithmétiques non signées


7 0 7 0
- Instruction CBW
Copie le SF d’un octet vers les bits de AH
AH AL
DATA1 DB +96
DATA2 DB +70
RESLT DW ?
---
SUB AH, AH ; 00h  AH
MOV AL, DATA1 ; Opérande 1
MOV BL, DATA2 ; Opérande 2
ADD AL, BL ; les additionner
JNO PASSE ; Si OF = 0 effectuer l’addition normalement et sauvegarder le résultat de AX
MOV AL, DATA2 ; sinon on corrige avec CBW. On commence avec l’ Opérande 2
CBW ; Note: CBW travaille toujours avec AL
MOX BX, AX ; sauvegarder dans BX
MOV AL, DATA1 ; correction avec l’ opérande 1
CBW ; Note: CBW travaille toujours avec AL
ADD AX, BX ; Additionner les deux opérandes après correction (extension du signe)
PASSE: MOV RESLT, AX ; sauvegarder le résultat de AX

- Instruction CWD 15 0 15 0

Copie le SF d’un mot vers les bits de DX


DX AX

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.

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


44/53

Opérations arithmétiques non signées


MULTIPLICATION ET DIVISION SIGNÉE (IMUL / IDIV) reg. (ou mém.)
Note: Dans les manuels d’Intel IMUL et IDIV pour Integer MULtiplication et DIVision (X et / des
nombres entiers) mais au fait il s’agit de Multiplication et Division des nombres signées.
DIVISION SIGNEE NUM. (> ou <) DENOM. (> ou <) QUOTIENT RESTE
Octet/Octet AL = Octet CBW Reg. ou mem. AL AH
Mot/Mot AX = Mot CWD Reg. ou mem. AX DX
Mot/Octet AX = Mot Reg. ou mem. AL (Erreur si –128>AL>+127) AH
DoubleMot/Mot DXAX = DoubleMot Reg. ou mem. AX (Erreur si –32768>AL>+32767) DX

MULTIPLICATION OPERANDE 1 OPERANDE 2 RESULTAT


SIGNEE (> ou <) (> ou <)
Octet/Octet AL Reg. ou mem. AX (CF=OF=1 si AH possède une partie du résultat,
mais si celui-ci n’est pas large  pas besoin de AH,
le bit de signe est copié aux bits non utilisés de AH et
la CPU force CF=OF=0 pour l’indiquer)

Mot/Mot AX Reg. ou mem. DXAX(CF=OF=1 si DX possède une partie du


résultat, mais si celui-ci n’est pas large  pas besoin
de DX, le bit de signe est copié aux bits non utilisés
de DX et la CPU force CF=OF=0 pour l’indiquer)

Mot/Octet AL = Octet Reg. ou mem. DXAX (même remarque que précédemment)


CBW
DoubleMot/Mot
R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs
45/53

Opérations arithmétiques non signées


TITLE PROG3_10.asm EXEMPLE D’UTILISATION DE IDIV  TROUVER LA TEMPERATURE MOYENNE
PAGE 60,132
.MODEL STMALL
.STACK 64
.DATA
SIGN_DAT DB +13,-10,+19,+14,-18,-9,+12,-9,+16
ORG 0010H
MOYENNE DW ?
RESTE DW ?
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX
MOV CX,9 ; Charger le compteur
SUB BX,BX ; Mettre a 0 le registre BX, utilisé comme accumulateur
MOV SI,OFFSET SIGN_DAT ; SI  SIGN_DAT
ARRIERE: MOV AL,[SI] ; Un octet de donnée  AL
CBW ; Extension du signe  AX
ADD BX,AX ; BX+AXBX
INC SI ; SI+1  SI
LOOP ARRIERE ; Boucler tant que CX > 0
MOV AL,9 ; Le nombre totales des températures  AL
CBW ; Extension du signe  AX
MOV CX,AX ; Sauvegarder le DENOMINATEUR dans CX
MOV AX,BX ; LA somme des températures  AX
CWD ; Extension du signe  AX
IDIV CX ; Trouver la moyenne des températures (AX/CX)
MOV MOYENNE,AX ; Sauvegarder la moyenne (QUOTIENT)
MOV REMAINDER,DX ; Sauvegarder le reste
MOV AH,4CH INT 21H ;Retourner au DOS
MAIN ENDP
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


46/53

Opérations arithmétiques non signées


TITLE PROG3_10.lst TROUVER LA TEMPERATURE MOYENNE
PAGE 60,132
0000 .MODEL STMALL
0000 .STACK 64
0000 .DATA
0000 0D F6 13 0E EE F7 0C ED 10 DB +13,-10,+19,+14,-18,-9,+12,-9,+16
0010 ORG 0010H
0010 0000 MOYENNE DW ?
0012 0000 RESTE DW ?
0014 .CODE
0000 MAIN PROC FAR
0000 B8 0000s MOV AX,@DATA
0003 8E D8 MOV DS,AX
0005 B9 0009 MOV CX,9
0008 2B DB SUB BX,BX
000A BE 0000r MOV SI,OFFSET SIGN_DAT
000D 8A 04 ARRIERE: MOV AL,[SI]
000F 98 CBW
0010 03 D8 ADD BX,AX
0012 46 INC SI
0013 E2 F8 LOOP ARRIERE
0015 B0 09 MOV AL,9
0017 98 CBW
0018 8B C8 MOV CX,AX
001A 8B C3 MOV AX,BX
001C 99 CWD
001D F7 F9 IDIV CX
001F A3 0010r MOV MOYENNE,AX
0022 89 16 0012r MOV REMAINDER,DX
0026 B4 4C MOV AH,4CH
0028 CD 21 INT 21H
002A MAIN ENDP
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


47/53

Décalage et Comparaison arithmétiques non signées

DECALAGE ARITHMETIQUE (SAR / SAL) REG NombreDeFois


Note: Contrairement au décalage logique, vue précédemment, dans le décalage arithmétique on tient
compte du bit de signe. SAR est utilisée pour diviser les nombres signées par 2.
L’instruction arithmétique SAL fait la même chose que son équivalente logique SHL vue précédemment.

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.

dest. > source  OF=SF ou ZF=0


dest. = source  ZF=1
dest. < source  OF=INV(SF)

JG ; Saut si OF=SF ou ZF=0
JGE ; Saut si OF=SF
JL ; Saut si OF=not(SF)
JLE ; Saut si OF=not(SF) ou ZF=1
JE ; Saut si ZF=1

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


48/53

Décalage et Comparaison arithmétiques non signées

TITLE PROG3_11.asm ;TROUVER LA TEMPERATURE LA PLUS BASSE


PAGE 60,132
;---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.MODEL SMALL
.STACK 64
;---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.DATA
SIGN_DAT DB +13, -10, +19, +14, -18, -9, +12, -9, +16
ORG 0010H
PLUS_BASSE DB ?
;---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX
MOV CX,8 ; Charger le compteur (nombre total - 1)
MOV SI,OFFSET SIGN_DAT ; SI  SIGN_DAT
MOV AL,[SI] ; La plus basse température trouvée (X) AL
ARRIERE: INC SI ; Incrémenter le pointeur
CMP AL,[SI] ; Comparer le prochain octet a X température
JLE CHERCHE ; Si AL contient X, continuer a chercher
MOV AL,[SI] ; Sinon sauvegarder le résultat
CHERCHE : LOOP ARRIERE ; Boucler tant que CX>0
MOV LOWEST,AL ; Sauvegarder la + basse température trouvée
MOV AH,4CH INT 21H ; DOS
MAIN ENDP
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


49/53
Section 3.7: Instructions des chaînes et
des tables de données
Les P80x86 possèdent des instructions sur des chaînes de caractères pour effectuer des
opérations avec des opérandes se trouvant dans des locations mémoire.

Instruction Mnémonique Destination Source Préfixe


Dep. Ch. Oct. MOVSB ES:SI DS:SI REP
Dep. Ch. Mot MOVSW ES:SI DS:SI REP
Sav. Ch. Oct. STOSB ES:SI AL REP
Sav. Ch. Mot STOSW ES:SI AX REP
Chg. Ch. Oct. LODSB AL DS:SI /
Chg. Ch. Mot LODSW AX DS:SI /
Cmp. Ch. Oct. CMPSB ES:SI DS:SI REPE/REPNE
Cmp. Ch. Mot CMPSW ES:SI DS:SI REPE/REPNE
Scn. Ch. Oct. SCASB ES:SI AL REPE/REPNE
Scn. Ch. Oct. SCASW ES:SI AX REPE/REPNE

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

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


50/53

Instructions des chaînes et des tables de données

Exemple: REP MOVSB et CLD

TITLE PROG3_12.asm ;Transfert un bloc de 20 octets dans la mémoire


PAGE 60,132
.MODEL SMALL
.STACK 64
.DATA
DATA_S DB ‘AQWERTTYUIOPLJKHGFDS’
ORG 0030H
DATA_D DB 20 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 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

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


51/53

Instructions des chaînes et des tables de données


Exemple: LODSB, REP STOSW et CLD

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’à CX0)
; 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 CX0
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

Instructions des chaînes et des tables de données


Exemple: REPE CMPSB et CLD

TITLE PROG3_14.asm ; Vérifier l’orthographe d’un mot et afficher un message


PAGE 60,132
.MODEL SMALL
.STACK 64
.DATA
MOT_EXACT DB ‘EUROPE’
MOT_TAPEE DB ‘EUORPE’
MESSAGE1 DB ‘L’orthographe est juste’ , ‘$’
MESSAGE2 DB ‘L’orthographe est fausse’ , ‘$’
.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 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

PASSE: MOV DX, OFFSET MESSAGE1


AFFICHAGE: MOV AH,09H ; le message est ‘Mémoire défectueuse’
INT 21H ; DOS

MAIN ENDP
END MAIN

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs


53/53

Instructions des chaînes et des tables de données

Exemple: REPNE SCASB et CLD

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

R. Beguenane, UQAC, 2002/2003 Systèmes à microprocesseurs

Vous aimerez peut-être aussi