Problème de saisie

Signaler
Messages postés
17
Date d'inscription
lundi 16 janvier 2006
Statut
Membre
Dernière intervention
4 avril 2006
-
Messages postés
116
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
10 avril 2013
-
Bonjour,

Voila, je dois faire une présentation en ASM.

1. Entrez un matricule de au moins et au maximum 4 chiffre uniquement
2. Saisir le nom et prenom de l'eleve
3. Saisir 2 cotes
4. Moyenne de ces 2 cotes

Mais j'ai un problème avec la saisie du matricule. Les lettres sont bloqué( OK ) mais la saisie ne s'arrete pas a 4 chiffre, elle continue sur la fenetre alors qu'elle devrait sauter a la saisie du nom. Je ne trouve pas d'ou cela provient.
Voila les sources, le programme principal et les procedures (la procedure matricule se situe tout a la fin). Si vous trouvez d'autre bug d'affichage ou autre merci de me le dire.
SVP tester, MERCI d'avance

Programme principale

.MODEL SMALL
.STACK
.DATA


carmatricule db 5,?,5 dup(' ')
carnom db 40,?,40 dup(' ')
carprenom db 40,?,40 dup(' ')
recommencer db 'Appuyer sur ENTER pour recommencer ou sur ESC pour arreter$'
nbrcote1 db ?
nbrcote2 db ?
moyene db 5 DUP(' ')
svg db ?
tmp1 db ?
tmp2 db ?


.CODE


INCLUDE e:\asm\ex\saisie.asm


;Début du programme
MAINPROG:


CALL ecran


MOV dh,5
MOV dl,40


CALL matri


MOV dh,10
MOV dl,14


CALL lettre


MOV dh,12
MOV dl,17


CALL lettre


;saisie nbr1


MOV DH, 14
MOV DL, 17 ;Position du curseur
CALL nombre
MOV nbrcote1,dl


;saisie nbr2


MOV dh,16
MOV dl,17 ;Position du curseur
CALL nombre
MOV nbrcote2,dl


MOV dh,20
MOV dl,19 ;Position du curseur
MOV ah,02h
INT 10h


MOV al,nbrcote1
ADD al,nbrcote2 ;Additon des 2 cotes
XOR ah,ah


MOV dx,2
CALL division


push ax ;Sauve le reste de la division


MOV bx,dx ;svg dx
ADD dx,dx ;2*dx
ADD dx,bx ;3*dx
ADD dx,bx ;4*dx
ADD dx,bx ;5*dx


CMP ax,0
JE ENTIER ;Si division entière
JNE REEL ;Si division avec reste


REEL:
INC DX
INC DX
MOV AX,DX
MOV bx,offset moyene

MOV di,5


SUITE2:


MOV dx,10
CALL DIVISION
ADD al,30h ;Récupere le chiffre
MOV [bx][di],al ;Place dans le vecteur
DEC di
MOV AX,DX
CMP AX,0
JA SUITE2
INC di


AFFICH1:


MOV dl,[bx][di]
MOV ah,02h
INT 21h
INC di
CMP di,5
JBE AFFICH1


MOV dl,',' ;Affiche une virgule
MOV ah,02h
INT 21h
MOV dl,'5' ;Affiche le reste
MOV ah,02h
INT 21h
JMP SUITE1


ENTIER:


MOV AX,DX
MOV bx,offset moyene

MOV di,5


SUITE3:


MOV dx,10
CALL DIVISION
ADD al,30h ;Récupere le chiffre
MOV [bx][di],al ;Place dans le vecteur
DEC di
MOV AX,DX
CMP AX,0
JA SUITE3
INC di


AFFICH2:


MOV dl,[bx][di]
MOV ah,02h
INT 21h
INC di
CMP di,5
JBE AFFICH2


MOV ah,02h
MOV dl,' ' ;N'affiche rien
INT 21h
MOV ah,02h
MOV dl,' ' ;N'affiche rien
INT 21h
MOV ah,02h
MOV dl,'%' ;Affiche le pourcentage
int 21h



SUITE1:


MOV dh,22
MOV dl,10 ;Positionne le curseur
MOV ah,02h
INT 10h


MOV dx,offset recommencer ;Demande à l'utilisateur si il veut recommencer
PUSh AX
MOV AX, 0900h
INT 21h
POP AX


MOV ah,1
INT 21h
CMP al,1Bh
JE FINPROG ;Si ESC
JNE SAUTRET ;Sinon aller SAUTRET


SAUTRET:


JMP MAINPROG ;Rcommencer


FINPROG:


MOV ax,4C00h
INT 21h


END MAINPROG




Procedures

.MODEL SMALL
.STACK 100h
.DATA
matricule db 'MATRICULE:....$'
nom db 'NOM:...........................................$'
prenom db 'PRENOM:.....................................$'
cote1 db 'COTE 1:../20$'
cote2 db 'COTE 2:../20$'
moyenne db 'MOYENNE :..,.%$'


.CODE
;Ecran
ECRAN PROC
MOV ax,@DATA
MOV ds,ax


MOV ah,0Fh
INT 10h


MOV ah,0h
INT 10h

MOV dh,5
MOV dl,30
MOV ah,02h
INT 10h

MOV dx,offset matricule
MOV ah,09h
INT 21h


MOV dh,10
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset nom
MOV ah,09h
INT 21h


MOV dh,12
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset prenom
MOV ah,09h
INT 21h


MOV dh,14
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset cote1
MOV ah,09h
INT 21h


MOV dh,16
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset cote2
MOV ah,09h
INT 21h


MOV dh,20
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset moyenne
MOV ah,09h
INT 21h


MOV dh,5
MOV dl,40
MOV ah,02h
INT 10h
RET
ECRAN ENDP


;Division
DIVISION PROC


PUSH si
PUSH di
PUSH cx


MOV si,ax
MOV di,dx
XOR ax,ax
XOR dx,dx
MOV cx,16
NEXT:
ROL si,1
RCL ax,1
ROL dx,1
CMP di,ax
JA NEXT2
INC dx
SUB ax,di
NEXT2:
LOOP NEXT
POP cx
POP di
POP si


RET
DIVISION ENDP


;Saisie Nombre
nombre PROC


MOV tmp1, DH ;Met dans tmp1 la valeur de DH
MOV tmp2, DL ;Met dans tmp2 la valeur de DL
PLACE:
MOV dh,tmp1 ;Met dans DH la valeur de tmp1
MOV dl,tmp2 ;Met dans DL la valeur de tmp2
MOV ah,02h
INT 10h


MOV ah,02h
MOV dl,'.'
int 21h


MOV ah,02h
MOV dl,'.'
int 21h


MOV dh,tmp1
MOV dl,tmp2
MOV ah,02h
INT 10h


MOV dx,0 ;Initialise le résultat
MOV cx,0


ENCORE1:


MOV ah,1
INT 21h


CMP al,0Dh ;Compare si ENTER
JNE SUIT1
CMP cx,0
JE POSITION
JNE FIN1


SUIT1:


CMP al,30h ;Compare si c'est un chiffre
JL POSITION ;Si il est plus petit POSITION
CMP al,39h ;Compare si c'est un chiffre
JG POSITION ;Si il est plus grand POSITION
AND al,0Fh ;Récupére le nombre


ROL dx,1 ;2*dx
MOV bx,dx ;sauve dx
ROL dx,1
ROL dx,1
ADD dx,bx ;10*dx


XOR ah,ah ;ah=0
ADD dx,ax ;Met le nombre dans DX
INC cx
CMP cx,2
JE FIN1
JMP ENCORE1


POSITION:


push dx
MOV dh,tmp1
MOV dl,tmp2
ADD dl,cl
MOV ah,02h
INT 10h
POP dx
JMP ENCORE1
FIN1:
CMP dl,0
JL PLACE
CMP dl,20
JG PLACE
RET
nombre ENDP


;Lettre


lettre PROC
main:
MOV ah,02h ;Positionne le curseur
INT 10h
MOV DI,0
MOV BL, 0


DEBUT1:


MOV ah,1 ;Saisie de la lettre
INT 21h
CMP al,0Dh ;Compare a ENTER
JE verif
CMP al,61h ;Compare la lettre
JL SUIT2 ;Si plus petit que 'a' SUIT2
CMP al,7Ah ;Compare la lettre
JG SUIT2 ;Si plus grande que 'z' SUIT2
MOV [BX][DI],al ;Met la lettre dans le vecteur
INC BL
INC di
CMP di,cx ;Saisie stopper apres un certain nombre de lettre
JE FIN
JMP DEBUT1


verif:
CMP BL, 0
JE main
JNE FIN


SUIT2:


push dx
push cx
mov cx,di
ADD dl,cl
MOV ah,02h
INT 10h ;Positionne le curseur


MOV ah,02h ;Efface la lettre
MOV dl,'.'
int 21h


pop cx ;Réinitialise CX et DX
pop dx


push dx
push cx


mov cx,di ;Repositionne le curseur pour recommencer la saisie
ADD dl,cl
MOV ah,02h
INT 10h


pop cx
pop dx


JMP DEBUT1 ;Retourne au début de la saisie
FIN:


RET
lettre ENDP



;Saisie matricule
matri PROC


MOV tmp1, DH ;Met dans tmp1 la valeur de DH
MOV tmp2, DL ;Met dans tmp2 la valeur de DL


MOV dx,0 ;Initialise le résultat
MOV cx,0


ENCORE4:


MOV ah,1
INT 21h


CMP al,30h ;Compare si c'est un chiffre
JB POSITION4 ;Si il est plus petit POSITION
CMP al,39h ;Compare si c'est un chiffre
JA POSITION4 ;Si il est plus grand POSITION
AND al,0Fh ;Récupére le nombre


ROL dx,1 ;2*dx
MOV bx,dx ;sauve dx
ROL dx,1
ROL dx,1
ADD dx,bx ;10*dx


XOR ah,ah ;ah=0
ADD dx,ax ;Met le nombre dans DX
INC cx
CMP cx,4
JE FIN4
JNE ENCORE4


POSITION4:


push dx
MOV dh,tmp1
MOV dl,tmp2
ADD dl,cl
MOV ah,02h
INT 10h
POP dx
JMP ENCORE4
FIN4:
RET
matri ENDP

3 réponses

Messages postés
116
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
10 avril 2013
1
Hello,
Pour ton problème de saisie qui continue sur la fenetre, modifie ces 3 lignes:

POSITION4:
push bx ;sauve bx
push dx
MOV dh,tmp1
MOV dl,tmp2
ADD dl,cl
xor bx,bx ;bx=0 => page 0
MOV ah,02h
INT 10h
POP dx
pop bx ;restore bx
JMP ENCORE4
FIN4:

D'autre part pour la lecture des touches, ce serait mieux d'utilisé:
1) la fonction 0Bh qui teste la présence d'une touche (dans une boucle),
2) la fonction 06h (avec dl=0FFh) qui lit la touche touche,
3) Vérifier si touche valide 0-9 (comme tu la fait)
4) la fonction 06h (avec dl=caractère) pour afficher la sortie a l'écran
Ca éviterait que les caractères invalides soit affichés (même un instant)

Ce qui donne:

matri PROC


xor bx,bx
MOV ah,02h
INT 10h ;Pos curseur


MOV dx,0 ;Initialise le résultat
MOV cx,4


L00: push dx


L01: mov ah,0Bh
int 21h
or al,al
jz L01 ;Attend touche


mov dl,0FFh
mov ah,006h
int 21h ;Lire la touche

CMP al,30h ;Compare si c'est un chiffre
JB L01 ;Si il est plus petit POSITION
CMP al,39h ;Compare si c'est un chiffre
JA L01 ;Si il est plus grand POSITION

push ax


mov dl,al
mov ah,06h
int 21h ;Affiche la touche validée


pop ax
AND al,0Fh ;Récupére le nombre
pop dx


ROL dx,1 ;2*dx
MOV bx,dx ;sauve dx
ROL dx,1
ROL dx,1
ADD dx,bx ;10*dx


XOR ah,ah ;ah=0
ADD dx,ax ;Met le nombre dans DX

dec cx
jnz L00
ret


matri ENDP

Bonne continuation
A+
Messages postés
17
Date d'inscription
lundi 16 janvier 2006
Statut
Membre
Dernière intervention
4 avril 2006

Merci pour ton aide mais le problème n'a pas changé.
Si je tape pour le matricule 4444, et que je continu a taper il ecrit a l ecran 4.4.4.4.4.4 a l infini alors qu'il devrait placer le curseur apres le nom.
Je ne sais pas si tu as tester mais chez moi ca ne fonctionne pas ?
Messages postés
116
Date d'inscription
samedi 4 juin 2005
Statut
Membre
Dernière intervention
10 avril 2013
1
Si le code est en 16 bits, c'est pas interdit d'utilisé les registre 32 bits a partir du 386
et ça simplifie les calculs... (de toute façon des 286 et prédécesseurs, a part au musée...)

Aussi pour calculer la moyenne et afficher le résultat avec 1 chiffre après la virgule
c'est plus simple de multiplier la somme par 10, de diviser par 2 et d'afficher le résultat avec
la virgule a la bonne place ;-)

.MODEL SMALL
.386
.STACK
.DATA
matricule db 'MATRICULE:....$'
nom db 'NOM:...........................................$'
prenom db 'PRENOM:.....................................$'
cote1 db 'COTE 1:../20$'
cote2 db 'COTE 2:../20$'
moyenne db 'MOYENNE :'
moyenneReel db '..,.%$'


carmatricule db 5 DUP ('$')
carnom db 41 DUP ('$')
carprenom db 41 DUP ('$')
CarCote1 db 3 DUP ('$')
CarCote2 db 3 DUP ('$')
recommencer db 'Appuyer sur ENTER pour recommencer ou sur ESC pour arreter$'
nbrcote1 dd ?
nbrcote2 dd ?


.CODE



MAINPROG:


CALL ecran


MOV dh,5
MOV dl,40
CALL matri


MOV dh,10
MOV dl,14
mov di,OFFSET carnom
CALL lettre


MOV dh,12
MOV dl,17
mov di,OFFSET carprenom
CALL lettre


MOV DH, 14
MOV DL, 17
mov di,OFFSET CarCote1
CALL nombre


MOV DH, 16
MOV DL, 17
mov di,OFFSET CarCote2
CALL nombre


mov si,OFFSET CarCote1
call Ascii2bin
mov nbrcote1,edx


mov si,OFFSET CarCote2
call Ascii2bin
mov nbrcote2,edx



add edx,nbrcote1
mov ecx,edx

imul ecx,10 ;ECX=somme*10
shr ecx,1 ;ECX=Moyenne*10



mov ebx,10 ;Facteur


mov eax,ecx
xor edx,edx
div ebx
mov ecx,eax


mov di,OFFSET moyenneReel+3
add dl,30h ;To ascii
mov [di],dl



mov eax,ecx
xor edx,edx
div ebx
mov ecx,eax


mov di,OFFSET moyenneReel+1
add dl,30h ;To ascii
mov [di],dl


mov eax,ecx
xor edx,edx
div ebx
mov ecx,eax


mov di,OFFSET moyenneReel
add dl,30h ;To ascii
mov [di],dl


MOV dh,20
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset moyenne
MOV ah,09h
INT 21h



MOV dh,22
MOV dl,10 ;Positionne le curseur
MOV ah,02h
INT 10h


MOV dx,offset recommencer ;Demande à l'utilisateur si il veut recommencer
MOV AX, 0900h
INT 21h


L10: call GetKey
cmp al,27
jz FINPROG
cmp al,13
jnz L10


mov eax,'.,..'
mov si,OFFSET moyenneReel
mov [si],eax


JMP MAINPROG ;Recommencer


FINPROG:


MOV ax,4C00h
INT 21h



;----------------------------------------------------------


ECRAN PROC
MOV ax,@DATA
MOV ds,ax


MOV ah,0Fh
INT 10h


MOV ah,0h
INT 10h

MOV dh,5
MOV dl,30
MOV ah,02h
INT 10h

MOV dx,offset matricule
MOV ah,09h
INT 21h


MOV dh,10
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset nom
MOV ah,09h
INT 21h


MOV dh,12
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset prenom
MOV ah,09h
INT 21h


MOV dh,14
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset cote1
MOV ah,09h
INT 21h


MOV dh,16
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset cote2
MOV ah,09h
INT 21h


MOV dh,20
MOV dl,10
MOV ah,02h
INT 10h

MOV dx,offset moyenne
MOV ah,09h
INT 21h


MOV dh,5
MOV dl,40
MOV ah,02h
INT 10h
RET
ECRAN ENDP


;----------------------------------------------------------


Ascii2bin PROC
xor edx,edx ;edx=Résultat
@@: xor eax,eax
mov al,[si]
inc si
cmp al,'$'
jz @F
sub al,30h
imul edx,10
add edx,eax
jmp @B
@@: ret
Ascii2bin ENDP


;----------------------------------------------------------


nombre PROC
MOV ah,02h ;Positionne le curseur
INT 10h
mov cx,2


@@: call GetKey
cmp al,13
jz VerifN


cmp al,'0'
jb @B
cmp al,'9'
jg @B


mov [di],al
inc di


mov dl,al
mov ah,06h
int 21h ;Affiche la touche validée


dec cx
jnz @B
ret


VerifN: cmp cx,2
Jz @B
ret
nombre ENDP


;----------------------------------------------------------


lettre PROC


MOV ah,02h ;Positionne le curseur
INT 10h
mov cx,40


@@: call GetKey
cmp al,13
jz Verif


cmp al,'A' ;Accept Minusc & Majusc
jb @B ;Mais pas les accents
cmp al,'z'
ja @B
cmp al,91
jz @B
cmp al,92
jz @B
cmp al,93
jz @B
cmp al,94
jz @B
cmp al,95
jz @B
cmp al,96
jz @B


mov [di],al
inc di


mov dl,al
mov ah,06h
int 21h ;Affiche la touche validée


dec cx
jnz @B
ret


Verif: cmp cx,40
Jz @B
ret
lettre ENDP


;----------------------------------------------------------


matri PROC


xor bx,bx
MOV ah,02h
INT 10h ;Pos curseur


mov cx,4
mov di,OFFSET carmatricule


@@: call GetKey


CMP al,30h ;Compare si c'est un chiffre
JB @B
CMP al,39h ;Compare si c'est un chiffre
JA @B


mov [di],al
inc di


mov dl,al
mov ah,06h
int 21h ;Affiche la touche validée


dec cx
Jnz @B
ret
matri ENDP


;----------------------------------------------------------


GetKey PROC
push bx
push cx
push dx


@@: mov ah,0Bh
int 21h
or al,al
jz @B ;Attend touche


mov dl,0FFh
mov ah,006h
int 21h ;Lire la touche
or al,al ;Touche étendue ?
jnz @F ;Non, on saute...
mov dl,0FFh
mov ah,006h
int 21h ;Lire la touche Etendue...
xor al,al ;...et la détruire!


@@: cmp al,27 ;Touche <ESC> ?
jnz @F ;Non,saute...
MOV ax,4C00h ;Oui,Termine Prog
INT 21h


@@: pop dx
pop cx
pop bx
ret
GetKey ENDP


END MAINPROG