gpt4 book ai didi

assembly - MASM程序集:存储浮点

转载 作者:行者123 更新时间:2023-12-02 14:42:56 25 4
gpt4 key购买 nike

我试图弄清楚如何将浮点存储到MASM中,并了解它是如何存储的。例如,如果我有电话号码:

1234.56_10 ;Base 10


我必须在哪里存储并将其转换为10。我必须怎么做才能存储 .56值?我当时想先存储 1234,然后将其转换为10。然后存储 .56,也将其转换,以后再将它们一起添加。

但是我的问题是存储 .56。我不知道如何存储它,也不知道如何将其存储到内存中。它以ASCII字符存储吗?还是存储方式不同?

最佳答案

MASM中基本上有三种不同的浮点类型:


REAL4

这等效于C的float类型,它是一个单精度浮点值,存储在4个字节中。其范围为±1.7×1038,具有6个有效数字。

格式为(从高位到低位):符号位,8位指数,23位尾数。 (前导1是隐式的。)


REAL8

这等效于C的double类型,它是一个双精度浮点值,存储在8个字节中。其范围为±1×10308,具有14个有效数字。

格式为(从高位到低位):符号位,11位指数,52位尾数。 (前导1是隐式的。)


TBYTE

这就是x87 FPU本机存储在其寄存器(作为堆栈实现)中的内容,通常等效于C的long double类型(如果编译器支持)。

它是一个10字节的值(类型名称的来源),范围为±104932,具有18个有效数字。

格式为(从高位到低位):符号位,15位指数,64位尾数,显式前导1。




(以上图像摘自链接的维基百科文章,并通过CC BY-SA 3.0许可。)

通常,您将要使用后两种格式之一,即REAL8TBYTE,因为您始终希望使用尽可能高的精度。另外,在x87上使用高精度类型不会对速度造成重大影响。 (唯一可以看到提速的方法是,如果将处理器限制为只能使用单精度类型,并且这样做会工作,并且由于精度的损失很大,这很可能不是您想要的。)

因此,让我们以64位REAL8格式为例。

在现实世界中,浮点值通常以“科学计数法”表示,它是以10为底的格式,例如1.81×103。在计算中,使用基于二进制的格式:1.0110101×27。本质上,符号为:尾数×2指数。 (尾数也称为“分数”部分。)

与往常一样,用于存储每个组件的位数决定了该组件的精度。在64位REAL8格式中,52位专门用于存储尾数(实际上是53位,因为有1个隐含位)。这样可以为您提供大约15个十进制数字的精度。

尾数的52位之前是11位,用于存储指数。指数字段偏向可用范围的中间,因此负指数实际上小于正指数。对于REAL8值,指数位的偏差为0x3FF。

最后,最高位是符号位。如果值为正,则设置为0;如果值为负,则设置为1。

因此,+ 1.0的值将具有REAL8格式的以下表示形式:

0 01111111111 0000000000000000000000000000000000000000000000000000
^ |----^----| |--------------------------^-----------------------|
| | |
| exponent mantissa
|
sign bit


或者,以更简单的十六进制表示法,为0x3FF0000000000000。

对于−1.0,一切保持不变,正负号被翻转:

1 01111111111 0000000000000000000000000000000000000000000000000000
^ |----^----| |--------------------------^-----------------------|
| | |
| exponent mantissa
|
sign bit


可以用 REAL8格式表示的最小可能值的指数为1,尾数为0(大约2.2×10-308):

0 00000000001 0000000000000000000000000000000000000000000000000000
^ |----^----| |--------------------------^-----------------------|
| | |
| exponent mantissa
|
sign bit


有些棘手的事情是可以用这种格式编码的特殊类型的值,例如无穷大,非数字(NaN)和非正规数,但您实际上不必担心这些。基本上,在 REAL8格式中,指数字段的最大值0x7FF表示无穷大或 NaN,而指数字段设置为0且非零尾数表示 "denormal" number。您将在Intel的x87 FPU文档中找到更详尽的说明以及所有上述信息(较旧的版本已镜像 here on John Loomis's site)。

但实际上,没有人考虑或手动进行这种转换。您要么让您的汇编器执行此操作,要么使用 a converter(在线上还有很多其他选择;我只是搜索和使用第一个弹出的那个)。

例如,如果我们不知道 FLDPI指令并想将π存储为 REAL8值怎么办?好了,我们插入了3.14159,然后看到它的二进制 REAL8表示为:

0 10000000000 1001001000011111100111110000000110111000011001101110
^ |----^----| |--------------------------^-----------------------|
| | |
| exponent mantissa
|
sign bit


或者,以十六进制形式: 0x400921F9F01B866E。当然,这是一个不精确的值,接近3.141589999…,但 floating-point is like that

关于您的问题,我想您一定是在滥用“基础10”一词。 1234.5610已经是以10为底的值-无需转换。如果将其以 REAL8格式存储,则为:

0 10000001001 0011010010100011111001110110110010001011010000111001
^ |----^----| |--------------------------^-----------------------|
| | |
| exponent mantissa
|
sign bit


或等效地, 0x40934A3E76C8B439。如果您有该功能,并且想将其转换回熟悉的10进制表示法,则必须按照我在此答案中描述的格式来解析该格式。老实说,我不知道为什么要这么做,但是如果您真的想要的话,现在可以了。我将使用 a converter:插入 40934A3E76C8B439,单击“圆形”,然后返回 1234.5610

否则,听起来您可能正在尝试重新发明 fixed-point arithmetic,它基本上将实数/十进制值存储为整数。您将 1234存储为一个整数,将 5610存储为另一个整数,然后将它们合并。小数点的位置是隐式的,可以出于显示目的将其重新添加。另请参阅: Fixed Point Arithmetic and Tricks (for the x86)

关于assembly - MASM程序集:存储浮点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43624902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com