开发者

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 =)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜