Intel x86 协处理器组装问题
我在理解如何检索使用 Intel x86 协处理器完成的计算结果时遇到一些困难。
请考虑以下数据段。
.data
res real4 ?
x real4 5.0
k real4 3.4
以及以下代码段,版本 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
和 版本 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
我理解版本 1,没有问题。
这是版本 2 我不明白。我可以在调试器中看到它执行与版本 1 相同的一些计算,但是当需要存储时,它会执行“41066666”!?
这是什么原因?
使用什么“编码”将 8.4 变成“41066666”?
有没有办法将其转换回 8.4,以便我可以在控制台中打印它(例如,使用 StdOut masm32 库函数)?
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
浮点计算器和转换器
输入8.4,可以看到十六进制版本数字表示为:41066666
Floating Pointt Calculator and Converter
Enter 8.4 and you can see the hex version of the number is represented as: 41066666
编码为 IEEE-754 浮点格式。您似乎正在使用 32 位浮点数,也称为单精度。这种格式包含一个符号位、一个偏移 127(也许是 128——我不记得了)的 8 位指数和 24 位尾数,其中存储 23,缺少的位是最重要的,通常具有值一,非正规值除外。有几种具有特殊含义的模式:零、NaN、无穷大和非正规数。
除了 CookieOfFortune 建议的外部工具之外,您还可以通过执行各种算术运算来确定值,从而编写浮点到 ASCII 的转换。有许多算法会以速度换取空间。查看
ftoa
,或printf()
的 %f 或 %g 转换。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 forprintf()
.0x41066666
是 8.4(准确地说,是 8.3999996185302734375)以 IEEE-754 单精度格式编码。您可以通过从编码中提取组件字段来轻松地将其值显示为十六进制数字,这将为您提供0x8.66666
,但将其转换为十进制相当难以正确完成。如果您想要十进制输出,最简单的方法是链接系统上的 C 库并使用 printf 函数。或者,正如 wallyk 建议的那样,获取其中一个开源转换例程的源代码(或者编写自己的实现,尽管这是一项令人惊讶的挑战性任务)。可能最容易访问的源位于 Netlibgdtoa.tgz >。该实现的复杂性应该会让您对所涉及的问题有所了解,并可能会引导您重新使用库 =)
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 you0x8.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 theprintf
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 =)