使用 64 位十六进制文字整数初始化 double 作为其位模式,就像编译器在 asm 中使用的那样

问题描述 投票:0回答:1

我有一个小型 C++ 32 位应用程序,具有以下变量赋值:

double unknown = -4.656612875e-10;

我想了解这是如何在汇编中表示的。显然它在 xmm0 中表示为

0xbe000000001c5f68

为了验证,我现在添加这一行:

double unknown1 = 0xbe000000001c5f68;

我原以为它会产生完全相同的组件,但结果不同。

    double unknown = -4.656612875e-10;
004F2265  movsd       xmm0,mmword ptr [__real@be000000001c5f68 (04F9BE8h)]  
004F226D  movsd       mmword ptr [unknown],xmm0  
    double unknown1 = 0xbe000000001c5f68;
004F2272  movsd       xmm0,mmword ptr [__real@43e7c0000000038c (04F9B40h)]  
004F227A  movsd       mmword ptr [unknown1],xmm0

我必须为

unknown1
分配什么十六进制值,以便汇编等于
unknown

c++ assembly floating-point constants type-punning
1个回答
1
投票

0xbe000000001c5f68
与整数文字
13690942867208167272
相同,因此您的
unknown1
被初始化为该值(与
-4e10
相差甚远,它的顺序为
1e19
)。

您在程序集中看到的是

-4.656612875e-10
具有与
0xbe000000001c5f68
(
BE 00 00 00 00 1C 5F 68
) 相同的八个字节的对象表示形式。您可以转换类型,同时保留对象表示,使用
std::bit_cast
重新解释这些位:

double unknown1 = std::bit_cast<double>(0xbe000000001c5f68u);

一般来说,这称为“类型双关”:保持对象表示不变。正常转换和强制转换保持表示的值相同或尽可能接近(例如,将双精度数截断为整数,或将大整数四舍五入为最接近的可表示双精度数)。


还有十六进制浮点文字,如下所示:

double unknown2 = -0x1.00000001c5f68p-31;

但它与对象表示并不一对一匹配。您可以看到尾数字段实际上是十六进制形式,但二进制 64 的前 12 位(符号和指数字段)是

(e + 1023) | (negative ? 0x800 : 0)
。对于此数字,
(-31 + 1023) | 0x800 == 0xbe0
,前 3 个十六进制数字。

© www.soinside.com 2019 - 2024. All rights reserved.