Affichage dans la memoire video

Affichage dans la memoire video - ASM - Programmation

Marsh Posté le 08-02-2006 à 21:01:01    

Bonjour,  
 
J'aimerais afficher l'heure dans la mémoire video mais je n'arrive pas à récuperer les chiffre pour les afficher.
j'utilise la fonction 1ch et j'ai dans al les heures.Je sais que je dois diviser par 16 mais je n'y arrive pas.
Voila ma dision pour récupere le code ascii. Apres l'appele de cette procedure je fais add al, 30h pour récuperer le code mais rien ne s'affiche.
Merci
 

Code :
  1. DIVISION PROC
  2.     PUSH SI
  3.     PUSH DI
  4.     PUSH CX
  5.     MOV SI, AX
  6.     MOV DI, DX
  7.     XOR AX, AX
  8.     XOR DX, DX
  9.     MOV CX, 16
  10. NEXT:
  11.     ROL SI, 1
  12.     RCL AX, 1
  13.     ROL DX, 1
  14.     CMP DI, AX
  15.     JA SUITE
  16.     INC DX
  17.     SUB AX, DI
  18. SUITE:
  19.     LOOP NEXT
  20.     POP CX
  21.     POP DI
  22.     POP SI
  23. RET
  24. DIVISION ENDP

Reply

Marsh Posté le 08-02-2006 à 21:01:01   

Reply

Marsh Posté le 09-02-2006 à 12:34:32    

Bonjour
L'énoncé n'est pas d'une grande limpidité et le code est tellement bien commenté que je ne parvient pas à saisir ce qu'il fait.
qu'est-ce qu'il faut diviser par 16 ?
s'agit-il de faire une conversion du nombre en AX vers sa représentation décimal en ascii ?
pour diviser par 16 le mieux est de faire un décalge à droite de 4 bits
soit : sar ax,4 ou shr ax,4 suivant que le nombre soit signé ou pas.
pour d'autre division le DIV ou IDIV peuvent être utilisés.

Reply

Marsh Posté le 09-02-2006 à 13:10:06    

+1, ça serait bien de fournir des explications et un code plus limpide parce que comme le dit db__, s'il suffit juste de diviser par 16, un simple décalage à droite suffit


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-02-2006 à 13:59:28    

db__ a écrit :

Bonjour
L'énoncé n'est pas d'une grande limpidité et le code est tellement bien commenté que je ne parvient pas à saisir ce qu'il fait.
qu'est-ce qu'il faut diviser par 16 ?
s'agit-il de faire une conversion du nombre en AX vers sa représentation décimal en ascii ?
pour diviser par 16 le mieux est de faire un décalge à droite de 4 bits
soit : sar ax,4 ou shr ax,4 suivant que le nombre soit signé ou pas.
pour d'autre division le DIV ou IDIV peuvent être utilisés.


 
la division par 16 ou le shift de 4 bits pour un affichage décimal implique que la veueur d'origine est en BCD.

Reply

Marsh Posté le 09-02-2006 à 14:22:49    

Le résultat de ta division est dans dx pas dans ax...
(Maiis, c'est quoi le nom de cet algo ? )


---------------
Scarmatil
Reply

Marsh Posté le 10-02-2006 à 13:10:03    

Citation :

la division par 16 ou le shift de 4 bits pour un affichage décimal implique que la veueur d'origine est en BCD.


lorsque la donnée (registre ou mémoire) est supposée être en binaire je maintient qu'un décalage de 4 bits effectue une division par 16.
lorsque la donnée est supposée être codée en Décimal Codé Binaire, un décalage de 4 bits effectue une division par 10 dans la mesure ou c'est un DCB compacté.
Si on veut convertir un nombre vers une représentation ascii en décimal, c'est beaucoup plus simple si le nombre est en DCB compacté ou non, un décalage de 4 bits sur une représentation binaire permet de faire une conversion vers de l'hexadécimal.
Un peu de code 32 bits cela nous changera un peu

Code :
  1. ; fonction traite32hexa
  2. ; entrée : edi -> pointe la chaine destination à l'endroit du chiffre le plus significatif
  3. ;  edx -> nombre 32 bits à convertir
  4. ; sortie edi -> pointe la chaine destination après le dernier chiffre inscrit
  5. ;  eax, ecx, edx perdus
  6. traite32hexa:
  7. mov ecx, 8    ; nombre de 8 chiffres
  8. lbl2: xor eax, eax
  9. shld eax, edx, 4   ; récupère les 4 bits de poids fort en eax
  10. shl edx, 4    ; shld ne modifie hélas pas edx
  11. add ch, ch    ; anule le bit AF car ch est nul -> indispensable
  12. aaa     ; convertit en dcb
  13. adc al, '0'    ; convertit en ascii en rajoutant la retenu de aaa
  14. shl ah, 4    ; pour ajustement si nécessaire -> issu de aaa
  15. add al, ah    ; rajoute 16 quand c'est nécessaire
  16. stosb     ; chiffre hexa en majuscule
  17. dec ecx
  18. jnz lbl2    ; boucle sur le nombre
  19. ret
  20. ; fonction traite32deci
  21. ; entrée : edi -> pointe la chaine destination à l'endroit du chiffre le plus significatif
  22. ;  ecx -> 10
  23. ;  eax -> nombre 32 bits à convertir
  24. ; sortie : edi -> pointe le dernier caractère entré
  25. ;  eax, edx perdus
  26. traite32deci:
  27. push edi
  28. add edi, ecx   ; se positionne 10 caractères plus loin
  29. mov [edi + 1], ch   ; met le 0 de fin de chaine
  30. lbl5: xor edx, edx   ; dividende edx:eax
  31. div ecx    ; quotient eax
  32. add dl, '0'    ; convertit le reste en ascii
  33. mov [edi], dl   ; met les unités dans la chaine
  34. dec edi    ; pointe les dizaines
  35. or eax, eax   ; y-a-t-il encore des chiffres
  36. jnz lbl5    ; oui -> on boucle
  37. mov edx, edi
  38. inc edx    ; pointe le premier chiffre du résultat
  39. pop edi    ; pointe le début du résultat
  40. mov al, [edx]
  41. stosb
  42. inc edx    ; pointe le caratère suivant
  43. or al, al    ; fin de chaine
  44. jnz lbl6    ; non -> on boucle
  45. ret


dans le cas 2, le nombre est supposée non signé.
le DIV est désastreux pour les performances. Si quelqu'un a mieux je suis preneur.
Je suis preneur pour une méthode ou des balises permettant d'avoir un résultat potable à l'écran

Reply

Marsh Posté le 10-02-2006 à 13:45:48    

db__ a écrit :

Citation :

la division par 16 ou le shift de 4 bits pour un affichage décimal implique que la veueur d'origine est en BCD.


lorsque la donnée (registre ou mémoire) est supposée être en binaire je maintient qu'un décalage de 4 bits effectue une division par 16.
lorsque la donnée est supposée être codée en Décimal Codé Binaire, un décalage de 4 bits effectue une division par 10 dans la mesure ou c'est un DCB compacté.
Si on veut convertir un nombre vers une représentation ascii en décimal, c'est beaucoup plus simple si le nombre est en DCB compacté ou non, un décalage de 4 bits sur une représentation binaire permet de faire une conversion vers de l'hexadécimal.
Un peu de code 32 bits cela nous changera un peu

Code :
  1. ; fonction traite32hexa
  2. ; entrée : edi -> pointe la chaine destination à l'endroit du chiffre le plus significatif
  3. ;  edx -> nombre 32 bits à convertir
  4. ; sortie edi -> pointe la chaine destination après le dernier chiffre inscrit
  5. ;  eax, ecx, edx perdus
  6. traite32hexa:
  7. mov ecx, 8    ; nombre de 8 chiffres
  8. lbl2: xor eax, eax
  9. shld eax, edx, 4   ; récupère les 4 bits de poids fort en eax
  10. shl edx, 4    ; shld ne modifie hélas pas edx
  11. add ch, ch    ; anule le bit AF car ch est nul -> indispensable
  12. aaa     ; convertit en dcb
  13. adc al, '0'    ; convertit en ascii en rajoutant la retenu de aaa
  14. shl ah, 4    ; pour ajustement si nécessaire -> issu de aaa
  15. add al, ah    ; rajoute 16 quand c'est nécessaire
  16. stosb     ; chiffre hexa en majuscule
  17. dec ecx
  18. jnz lbl2    ; boucle sur le nombre
  19. ret
  20. ; fonction traite32deci
  21. ; entrée : edi -> pointe la chaine destination à l'endroit du chiffre le plus significatif
  22. ;  ecx -> 10
  23. ;  eax -> nombre 32 bits à convertir
  24. ; sortie : edi -> pointe le dernier caractère entré
  25. ;  eax, edx perdus
  26. traite32deci:
  27. push edi
  28. add edi, ecx   ; se positionne 10 caractères plus loin
  29. mov [edi + 1], ch   ; met le 0 de fin de chaine
  30. lbl5: xor edx, edx   ; dividende edx:eax
  31. div ecx    ; quotient eax
  32. add dl, '0'    ; convertit le reste en ascii
  33. mov [edi], dl   ; met les unités dans la chaine
  34. dec edi    ; pointe les dizaines
  35. or eax, eax   ; y-a-t-il encore des chiffres
  36. jnz lbl5    ; oui -> on boucle
  37. mov edx, edi
  38. inc edx    ; pointe le premier chiffre du résultat
  39. pop edi    ; pointe le début du résultat
  40. mov al, [edx]
  41. stosb
  42. inc edx    ; pointe le caratère suivant
  43. or al, al    ; fin de chaine
  44. jnz lbl6    ; non -> on boucle
  45. ret


dans le cas 2, le nombre est supposée non signé.
le DIV est désastreux pour les performances. Si quelqu'un a mieux je suis preneur.
Je suis preneur pour une méthode ou des balises permettant d'avoir un résultat potable à l'écran


 
on est d'accord (enfin j'ai pas regardé le code, surtout l'histoire du BCD/DCB :D)

Reply

Marsh Posté le 20-02-2006 à 18:30:55    

Citation :

le DIV est désastreux pour les performances. Si quelqu'un a mieux je suis preneur.


 
Déjà il y a le truc de multiplier par l'inverse au lieu de diviser... Je connaissais ce truc pour trouver le quotient mais on peut l'adapter pour trouver le reste également.
Principe: précalculer (2^32 / 10). Multiplier par cette valeur et garder les 32 bits de poids fort revient à diviser par 10...
Il faut arrondir vers le haut (2^32 / 10) sinon le résultat sera incorrect. Malgré tout, la division n'étant pas exacte, le résultat pourra être erroné mais seulement pour de grandes valeurs du dividende (de l'ordre de 2^30). Suivant l'application ça peut être un problème ou non...
Pour trouver le reste, on prend les 32 bits de poids faible de la multiplication précédente qu'on multiple par 10. Les 32 bits de poids fort de ce résultat forme le reste.
 
exemple:
eax = n
ecx = 10
ebx = 429496730
 
mul ebx
; edx contient (n/10)
mul ecx
; edx contient (n%10)
 
Maintenant, je ne sais pas si deux multiplications c'est mieux qu'une division sur les CPU actuels...
Qu'en pensez-vous ?

Reply

Marsh Posté le 21-02-2006 à 12:44:45    

Bonjour
l'astuce est effectivement interessante mais elle a un inconvénient de taille c'est comme tu le signale qu'elle n'est pas universelle et ne fonctionne pas avec les très grands nombres or pour beaucoup d'application, il n'y a pas de présupposition sur le nombre.
Elle a un autre petit inconvénient pour moi, elle consomme un registre en plus
déjà qu'avec 7 registres c'est pas facile et le push pop n'est pas nécessairement économique.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed