1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
| PAGE 64,132
; Demande l'entrée d'un nombre entier décimal pouvant être stocké dans un
; double-mot signé de 32 bits.
; Assemblage :
; MASM DEC2HEX;
; LINK DEC2HEX;
; EXE2BIN DEC2HEX DEC2HEX.COM
CGROUP GROUP CODE, DATA?
LgNombre equ 11
CODE SEGMENT
ASSUME CS:CODE, DS:CGROUP
ORG 100h
Depart:
mov Somme,0 ; Initialise le double-mot Somme
mov Somme+2,0
mov ah,9 ; Affiche message
mov dx,offset MsgEntree
int 21h
mov ah,0Ah ; Attend entrée
mov dx,offset TeteTampon
int 21h
call LireDecimalSgn
jnc Sortie ; Si pas d'erreur, sortie hexa
cmp ax,1 ; Erreur de frappe ?
jne Err2
mov ah,9
mov dx,offset MsgTypo
int 21h
jmp Depart ; Recommencez entrée
Err2:
cmp ax,2 ; Erreur de débordement ?
jne fin ; Si inégal, erreur inconnue
mov ah,9
mov dx,offset MsgDebord
int 21h
jmp Depart ; Recommencez entrée
Sortie:
mov ah,9
mov dx,offset MsgSortie
int 21h
std ; Direction : décrémentation
mov cx,4 ; Double-mot (4 octets)
mov si,offset ds:Somme+3 ; Octet de poids fort
Affiche_octet:
lodsb ; AL = DS:[SI] et DEC SI
call AfficheHexa ; Affiche les 2 chiffres hexa
loop Affiche_octet
Fin:
ret ; Fin
PAGE
LireDecimalSgn PROC
; Lit le nombre décimal signé dans la chaîne Tampon avant de le traduire dans
; le double-mot Somme.
; Entrée : DS:SI pointe la chaîne dont le 1er octet donne le nb de car.
; Sortie : Si succès, bit de retenue effacé et AX = 0
; Si échec, bit de retenue positionné, AX = code d'erreur
; Code d'erreur : 1, erreur de frappe
; 2, erreur de débordement
; Lit : Tampon
; [1er car. : nb de car. (éventuel sgn "-" puis chiffres)]
; Ecrit : Somme (double-mot)
; Procédure utilisée : PuissDix
push bx
push cx
push dx
push si
pushf ; sauve le registre d'état car CLD
cld ; Direction : incrémentation
xor ch,ch ; CH = 0
mov cl,Tampon ; Nb de caractères
mov si,offset ds:Tampon+1 ; DS:SI pointe le premier caractère
cmp byte ptr [si],'-' ; Négatif ?
jne Boucle
dec cx ; Nombres de chiffres si négatif
inc si ; Pointe le premier chiffre
Boucle:
lodsb ; AL = DS:[SI] et INC SI
cmp al,'0'
jb Err_typo
cmp al,'9'
ja Err_typo
sub al,'0' ; Valeur du chiffre dans AL
xor ah,ah ; AH = 0
xor dx,dx ; DX = 0
dec cx ; Exposant = compteur - 1
call PuissDix ; DX:AX = (DX:AX).10^CX
jc Err_debord1 ; Erreur ?
or dx,dx
js Err_debord1 ; Nb négatif ?
inc cx
add Somme,ax ; Addition des mots de poids faible
adc Somme+2,dx ; Add. avec retenue des mots de pds fort
jc Err_debord1 ; Retenue ?
jo Err_debord2 ; Débordement ?
loop Boucle ; Déc. CX et recommence si non nul
PAGE
cmp Tampon+1,'-' ; Rendre négatif ?
jne Retour_bon
neg Somme ; Complément à 2 du mot de poids faible
jnz Non_reversible ; Si poids faible nul,
dec Somme+2 ; décrémentation du poids fort
Non_reversible:
not Somme+2 ; Complément à 1 du mot de poids fort
Retour_bon:
xor ax,ax
popf
clc ; CF = 0
Retour_mauvais:
pop si
pop dx
pop cx
pop bx
ret
Err_typo:
mov ax,1
jmp short Erreur
Err_debord2:
cmp word ptr Somme,0
jne Err_debord1
cmp word ptr Somme+2,8000h
jne Err_debord1
cmp Tampon+1,'-'
je Retour_bon ; Plus petit nombre possible
Err_debord1:
mov ax,2
Erreur:
popf
stc ; CF = 1
jmp Retour_mauvais
LireDecimalSgn ENDP
PAGE
PuissDix PROC
; Stocke (DX:AX).10^CX dans l'entier non signé DX:AX
; Entrée : DX:AX multiple non signé
; CX exposant non signé
; Sortie : Si bit de retenue effacé,
; DX:AX résultat après facteur 10 puissance CX
; sinon débordement.
push bx
push cx
push si
push di
jcxz Ret_PuissDix ; Si CX nul, retour
mov bx,10 ; BX : multiplicateur 10
mov si,dx ; SI <- poids fort
FoisDix:
xchg di,ax ; DI <- poids faible
xchg ax,si ; AX <- poids fort
mul bx ; DX:AX (poids fort) = AX x 10
or dx,dx ; DX nul ?
jnz Debordement ; Si non, erreur (32 bits insuff.)
xchg si,ax ; SI <- poids fort
xchg ax,di ; AX <- poids faible
mul bx
add si,dx ; Retenue dans le poids fort
loop FoisDix
mov dx,si ; DX <- poids fort
clc ; CF = 0
Ret_PuissDix:
pop di
pop si
pop cx
pop bx
ret
Debordement:
stc ; CF = 1
jmp Ret_PuissDix
PuissDix ENDP
PAGE
AfficheHexa PROC
; Affiche l'octet an AL sous forme de 2 chiffres hexa.
; Entrée : AL octet à afficher
; Procédure utilisée : SortChiffreHexa
push ax
push cx
mov ah,al ; Sauve AL dans AH
mov cl,4
shr al,cl ; AL : quartet de poids fort
call SortChiffreHexa
mov al,ah ; Restitue AL
and al,0Fh ; AL : quartet de poids faible
call SortChiffreHexa
pop cx
pop ax
ret
AfficheHexa ENDP
SortChiffreHexa PROC
; Affiche un chiffre hexa stocké dans AL.
; Entrée : AL chiffre hexa
push ax
push dx
; Ex. : 0Ah | 00h
add al,90h ; 9Ah | 90h
daa ; (1)00h | 90h
adc al,40h ; 41h | D0h
daa ; 41h -> 'A' | (1)30h -> '0'
xchg dx,ax ; DL <- AL
mov ah,2 ; Affiche caractère
int 21h
pop dx
pop ax
ret
SortChiffreHexa ENDP
; Données -------------------------------------------------------------------
MsgEntree db 13,10,'Entier décimal à convertir :',13,10,'$'
MsgTypo db 13,10,'Caractères autres que les chiffres et le signe '
db '"-" refusés. Recommencez.$'
MsgDebord db 13,10,'Nombre hors limites. Recommencez.$'
MsgSortie db 13,10,"L'équivalent hexadécimal est :",13,10,'$'
; Donne le nombre d'octets nécessaire à l'entrée du nombre pour DOS
TeteTampon db LgNombre+1 ; Précède Tampon
CODE ENDS
DATA? SEGMENT BYTE
; Prend en compte l'enregistrement de la touche Entrée (car. 13)
Tampon db LgNombre+2 dup(?) ; Suit TeteTampon
Somme dw 2 dup(?)
DATA? ENDS
END Depart |
Partager