0

当以下运行时,我得到 _pfloatPos 和 _charPos 不同:

    float* const _pData = new float[0x50000000];

    float*  const _floatPos = _pData + 0x400000B0;
    char*   const _charPos = ((char*)_pData) + 0x400000B0 * 4;

    if ((char*)_floatPos !=  _charPos)
    {
        throw "Derp.";
    }

也许我脑子有雾,错过了一些基本的东西。这两个地址应该是一样的吧?

我看着拆机。1000002C0h 是 4 * 0x400000B0 。对于第二个,它似乎在某些时候被截断了。

        float*  const _floatPos = _pData + 0x400000B0;
00007FF7CE48F6E2  mov         rax,1000002C0h  
00007FF7CE48F6EC  mov         rcx,qword ptr [_pData]  
00007FF7CE48F6F0  add         rcx,rax  
00007FF7CE48F6F3  mov         rax,rcx  
00007FF7CE48F6F6  mov         qword ptr [_floatPos],rax  
        char*   const _charPos = ((char*)_pData) + 0x400000B0 * 4;
00007FF7CE48F6FA  mov         rax,qword ptr [_pData]  
00007FF7CE48F6FE  add         rax,2C0h  
00007FF7CE48F704  mov         qword ptr [_charPos],rax  

我使用的是 Visual Studio 2017 版本 15.9.2,但我不确定编译器的版本。

4

2 回答 2

2

您需要0x400000B0 * 4L,否则乘法将溢出。

于 2019-01-16T20:42:51.013 回答
1

我猜大卫的答案适用于某些编译器,但在 Microsoft 编译器中,我仍然收到警告和相同的结果。我注意到在一些 C++ 文档中,“long”只提供“至少 32 位的宽度”。因此我将变量类型和表达式类型改为long long;

long long _varLLxxLL = 0x400000B0 * 4LL;
std::cout << "_varLLxxLL has value " << _varLLxxLL 
          << ", the expression had type " << typeid(0x400000B0 * 4LL).name() << "\n";

输出:

_varLLxxLL 的值为 4294968000,表达式的类型为 __int64

相比于:

long _varLxxxLx = 0x400000B0 * 4L;
std::cout << "_varLxxxLx has value " << _varLxxxLx 
          << ", the expression had type " << typeid(0x400000B0 * 4L).name() << "\n";

输出:

_varLxxxLx 的值为 704,表达式的类型为 long

我暂时把这个问题留着。

于 2019-01-17T22:01:19.190 回答