; 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
or ax,ax
jz Sortie ; Si pas d'erreur, sortie hexa
js Err_debord
mov ah,9 ; Erreur de frappe
mov dx,offset MsgTypo
int 21h
jmp Depart ; Recommencez entrée
Err_debord:
mov ah,9 ; Erreur de débordement
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
LireDecimalSgn PROC
; Lit le nombre décimal 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 : AX= 0, aucune erreur
; AX= 1, erreur de frappe
; AX=-1, 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
cmp Tampon+1,'-' ; Rendre négatif ?
jne Retour_bon
neg Somme ; Complément à 2 du mot de poids faible
adc Somme+2,0 ; Si poids faible nul, complément à 2
neg Somme+2 ; du mot de poids fort ; sinon à 1.
Retour_bon:
xor ax,ax
popf
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,-1
Erreur:
popf
jmp Retour_mauvais
LireDecimalSgn ENDP
PuissDix PROC
; Stocke (DX:AX).10^CX dans DX:AX
; Entrée : DX:AX multiple
; CX exposant
; Sortie : Si bit de retenue effacé,
; DX:AX résultat de AL fois 10 puissance CX
; Si bit de retenue positionné, erreur de 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
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. : 0A | 00
cmp al,10 ; 0A | (FF)00
sbb al,69h ; (FF)A1 | (FF)96(AF=1)
das ; (FF)41 | (FF)30(AF=1)
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