2010-01-20 3 views
1

Je n'arrive pas à comprendre comment récupérer le résultat d'un calcul effectué avec le coprocesseur x86 d'Intel.Question sur l'assemblage du coprocesseur Intel x86

Veuillez prendre en compte le segment de données suivant.

et les segments de code suivants, version 1:

.code 

main: 

fld x  ; 5.0 
fadd k1 ; 5.0 + 3.4 
fistp res ; store as integer (it will round, in this case down) 

mov eax, res ; eax = 00000008 

end main 

et version 2:

.code 

main: 

fld x  ; 5.0 
fadd k ; 5.0 + 3.4 
fstp res ; store as real 

mov eax, res ; eax = 41066666 

end main 

Je comprends version 1, sans problème. Il s'agit de version 2 Je ne comprends pas. Je peux voir dans le débogueur qu'il fait le calcul exact en tant que version 1, mais quand il est temps de stocker est fait comme "41066666" !?

Pour quelle raison?
Quel "encodage" a été utilisé pour faire 8.4 en "41066666"?
Existe-t-il un moyen de le convertir à 8.4, de sorte que je puisse l'imprimer dans la console (par exemple, en utilisant la fonction de bibliothèque StdOut masm32)?

Merci.

Répondre

4

Floating Pointt Calculator and Converter

Entrez 8.4 et vous pouvez voir la version hexadécimale du numéro est représenté comme: 41066666

+0

Merci. Ceci explique cela. S'il vous plaît prenez le temps de répondre à l'autre partie de la question: Y at-il un moyen de le convertir en 8.4 pour que je puisse l'imprimer dans la console? Merci. – nunos

+0

Eh bien ... la façon dont je le ferais en C serait d'appeler printf (% f, x). Quelle bibliothèque utilisez-vous? Il y a peut-être une fonction là-dedans pour le convertir pour vous. – CookieOfFortune

+0

Comme mentionné dans le post, j'utilise masm32. Je ne sais pas, mais il y a peut-être une fonction masm32, comme dwtoa, mais pour les flotteurs qui peuvent le faire. – nunos

3

L'encodage est IEEE-754 format en virgule flottante. Il semble que vous utilisiez des flottants 32 bits, également connus sous le nom de précision simple. Ce format contient un bit de signe, un exposant de huit bits qui est biaisé par 127 (peut-être 128-je ne me souviens pas) et 24 bits de mantisse où 23 sont stockés et le bit manquant est le plus significatif et a généralement la valeur un, sauf pour les valeurs dénormales. Il existe plusieurs modèles ayant une signification particulière: zéro, NaN, infini et dénormaux. En plus de l'outil externe suggéré par CookieOfFortune, vous pouvez écrire une conversion en virgule flottante en ASCII en effectuant une variété d'opérations arithmétiques pour déterminer la valeur. Il existe de nombreux algorithmes qui traitent la vitesse de l'espace. Voir une source de bibliothèque d'exécution pour ftoa ou les conversions% f ou% g pour printf().

3

0x41066666est 8.4 (bien, 8.3999996185302734375 pour être exact) codé dans le format de précision simple IEEE-754. Vous pouvez facilement afficher sa valeur en tant que nombre hexadécimal en extrayant les champs de composant de l'encodage, ce qui vous donnerait 0x8.66666, mais la convertir en décimal est plus difficile à faire correctement. Si vous voulez avoir une sortie décimale, le plus simple est de lier la bibliothèque C sur votre système et d'utiliser la fonction printf.

Sinon, comme wallyk suggéré, saisir la source pour l'une des routines de conversion open source (ou écrire votre propre implémentation, bien que ce soit une tâche de bien faire étonnamment difficile). Probablement les meilleures sources facilement accessibles sont dans le fichier gdtoa.tgz sur Netlib.La complexité de cette implémentation devrait vous donner une idée des problèmes impliqués, et peut vous renvoyer vers l'utilisation d'une bibliothèque =)