Intel x86 coprocessor assembly question
I am having some trouble understanding how to retrieve the result of a calculation done using the Intel's x86 coprocessor.
Please consider the following data segment.
.data
res real4 ?
x real4 5.0
k real4 3.4
and the following code segments, 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
and 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
I understand version 1, with no problem.
It's version 2 I don't understand. I can see in the debugger that it does the exact some calculation as version 1, but when it's time to store is does so as "41066666"!?
What is the reason for this?
What "encoding" was used to make 8.4 into "41066666"? Is there a way to convert it back to 8.4, so that I can print it in the console (for example, using StdOut masm32 library function)?Thanks.
Floating Pointt Calculator and Converter
Enter 8.4 and you can see the hex version of the number is represented as: 41066666
The encoding is IEEE-754 floating point format. It appears you are using 32-bit floats, also known as single-precision. This format contains a sign bit, an eight bit exponent which is biased by 127 (maybe 128—I don't remember offhand), and 24 bits of mantissa where 23 are stored and the missing bit is the most significant and usually has the value one, except for denormal values. There are several patterns with special meaning: zero, NaN, infinity, and denormals.
Besides the external tool suggested by CookieOfFortune, you could write a floating point conversion to ASCII by performing a variety of arithmetic operations to determine the value. There are many algorithms which tradeoff speed for space. See any runtime library source for ftoa
, or the %f or %g conversions for printf()
.
0x41066666
is 8.4 (well, 8.3999996185302734375 to be exact) encoded in the IEEE-754 single precision format. You can easily display its value as a hexadecimal number by extracting the component fields from the encoding, which would give you 0x8.66666
, but converting it to decimal is rather harder to do correctly. If you want to have decimal output, the easiest thing is to link against the C library on your system and use the printf
function.
Alternatively, as wallyk suggested, grab the source for one of the open source conversion routines (or write your own implementation, though this is a surprisingly challenging task to do well). Probably the best easily accessible sources are in the file gdtoa.tgz
on Netlib. The complexity of that implementation should give you some idea of the issues involved, and may point you back toward using a library =)
精彩评论