Précédent   Forum du club des développeurs et IT Pro > Autres langages > Assembleur > Contribuez
Contribuez Contribuez à la FAQ Assembleur ou partagez vos sources
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 05/03/2011, 18h26   #1
edfed
Membre chevronné
 
Avatar de edfed
 
être humain
Inscription : décembre 2007
Messages : 471
Détails du profil
Informations professionnelles :
Activité : être humain

Informations forums :
Inscription : décembre 2007
Messages : 471
Points : 619
Points : 619
Par défaut bin2fdec -padding pour faire 12 caractères

comme les codes precedement postés ici, ceci est un aide mémoire.

celui ci couvre le code necessaire à la convertion d'un nombre decimal en une chaine de caractères terminée par 0.

l'algo est de mise en oeuvre super simple, et permet entre autre de faire dans la virgule fixe, et la virgule flottante (avec des adaptations evidement).

la chaine de base, ici str db "0000.000", contient un point décimal permettant d'interpreter eax en tant que valeur en virgule fixe, à 3 decimales apres la virgule.

Code :
1
2
3
4
5
6
7
8
 
mov eax,[valeur]
mov ebx,str.end
mov edi,str
call fixeddecimal
;ebx = chaine de caractère
mov eax,ebx
call printf ;afficher la chaine pointée par eax
la structure invoquée par cette fonction est comme suit:
Code :
1
2
3
4
 
valeur dd ?
str db "0000.000"
.end db 0
et enfin, la fonction en elle même
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
fixeddecimal:
        mov ecx,10
.loop:
        dec ebx
        cmp byte[ebx],'.'
        jne @f
        dec ebx
@@:
        cmp ebx,edi
        jl .end
        xor edx,edx
        div ecx
        or edx,edx
        jne @f
        or eax,eax
        jne @f
        mov dl,' '-'0'
@@:
        add dl,'0'
        mov [ebx],dl
        jmp .loop
.end:
        ret
Vous voyez, ce n'est pas bien compliqué.

Et si l'on veut juste un nombre sans point décimal, il suffit de ne pas déclarer de point dans la chaine de destination.

Personnelement, j'utilise cette fonction pour toutes les conversions binaire vers décimal, avec ou sans virgule fixe.
l'avantage est certain car il permet de n'avoir qu'une seule fonction pour ces deux actions.

pour la virgule flottante, il y aura donc lieu de proceder à une conversion.
tou d'abord, determiner la position de la virgule avec la FPU (ou SSE), multiplier par la puissance necessaire à la disparition de la virgule. et enfin, convertir en binaire (fist)
suite à ça, il y aura lieu de creer la chaine de reception, avec le point decimal à la bonne position, et le tour est joué.

il est aussi possible, à moindre frais, d'utiliser le format BCD de la FPU pour charger directement un nombre décimal, et juste extraire chaque nibble, puis aditionner la valeur du "0" ascii, et enfin, l'envoyer dans la chaine.
__________________
http://www.pending.me.uk/nmc/bla_1356091200.png
Vivement 21/12/2012
edfed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2011, 22h56   #2
Chevalier au taureau
Membre confirmé
 
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 48
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Industrie

Informations forums :
Inscription : juin 2007
Messages : 48
Points : 291
Points : 291
Moi j'ai ça :
Code :
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
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; nombreVersChaine													;;
;;------------------------------------------------------------------;;
;; Ecrit dans la chaîne pointée par EDI le nombre contenu dans EAX	;;
;; si CL est à un, on écrit un caractère terminal					;;
;; CH contient le nombre minimal de caractères à utiliser			;;
;; EBX contient la base												;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
nombreVersChaine:
	push 	edx
	push 	ecx
	xor		cl, cl
.stocke_digit:
	xor 	edx, edx
	div 	ebx
	push 	edx 			; Sauve le reste dans la pile
	inc 	cl
	or 		eax, eax		; Si le quotient n'est pas nul
	jne 	.stocke_digit	; on recommence
;Les digits sont stockés dans la pile
.ajout_zero:
	cmp 	ch, cl
	jbe		.clearCH
	push 	' '-'A'+10		; Nombre magique permettant de remplir avec des espaces
	inc 	cl
	jmp 	.ajout_zero
.clearCH:
	xor 	ch, ch
;Affichage du chiffre : On en affiche au moins un : zéro
.affiche_digit:
	pop 	eax
	cmp 	al, 10
	jae 	.dixPlus
	add 	al, '0'
	stosb 					; met AL dans l'octet pointé par EDI et incrémente EDI
	jmp 	.boucle_digit
.dixPlus:					; Pour les bases à plus de 10 chiffres, on utilise l'alphabet
	add 	al, 'A' - 10
	stosb
	jmp 	.boucle_digit
.boucle_digit:
	loop 	.affiche_digit
	pop 	ecx 			; on récupère le paramètre cx
	test 	cl, 0b1 		; s'il est à 1, on écrit un caractère terminal
	jz 		.depile
	mov 	byte [edi], 0
.depile:
	pop 	edx
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Fin nombreVersChaine											;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ca écrit dans n'importe quelle base, j'ai pas testé au-delà de la base 36 où il peut y avoir des problèmes. Ca ne fait pas les nombres à virgule flottante, ça termine la chaîne au besoin et ca complète une chaîne si spécifié.
Chevalier au taureau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/03/2011, 03h58   #3
edfed
Membre chevronné
 
Avatar de edfed
 
être humain
Inscription : décembre 2007
Messages : 471
Détails du profil
Informations professionnelles :
Activité : être humain

Informations forums :
Inscription : décembre 2007
Messages : 471
Points : 619
Points : 619
bein, pour n'importe quelle base, suffit de remplacer 10 par la base.
si en plus BASE est entrée dans ecx au moment d'appeler cette fonction
Code :
1
2
3
4
5
6
 
mov ecx,base
mov eax,num
mov ebx,finstring
mov edi,string
call fixedbase
...
methode très maladroite, mais bon, quand on aime passer les paramètres par les registres, on ne compte pas voyons.

Code :
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
 
fixedBASE:
        push ecx
.loop:
        pop ecx
        push ecx
        dec ebx
        cmp byte[ebx],'.'
        jne @f
        dec ebx
@@:
        cmp ebx,edi
        jl .end
        xor edx,edx
        div ecx
        or edx,edx
        jne @f
        or eax,eax
        jne @f
        mov dl,' '-'0'
@@:
        add dl,'0'
        mov [ebx],dl
        jmp .loop
.end:
        ret
tout ça pour juste convertir en décimal, tant qu'a faire, pour un bon compromis (chose due), on crée un truc par dessus pour prendre le controle centralisé des bases...

par exemple, un drapeau, mais là, on complique le code... pour rien au final car chaque base permet ses propres algorythmes optimisés.
la base 10 est une de celles qui ne donne pas trop dans l'optimisation. sauf peut etre avec les instructions AAM, AAD. qui permettent de diviser et multiplier par 10, ou tout autre base.

non mais ça me convenait parfaitement comme code pour convertir du decimal, pour le binaire, pas besoin de division, pour l'hexa non plus.
et je vois pas de base autre que 10 à utiliser dans la vie de tout les jours.
__________________
http://www.pending.me.uk/nmc/bla_1356091200.png
Vivement 21/12/2012
edfed est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 10h23.


 
 
 
 
Partenaires

Hébergement Web