C ++在64位Windows 7和32位Windows XP上使用Visual Studio C ++ 2010 Express编译(来自同一来源)DLL。 Windows 7上的外部64位应用程序调用DLL并正确执行。 Windows XP上的等效32位应用程序在DLL调用返回时发生堆栈或内存损坏。
尝试调试这个我设置了一个断点,DLL将数据从一些内部结构复制到外部应用程序想要的内容,返回之前的最后一步。在给定的点上,我在Visual Studio中看到类似的东西: destination [i] .field = source [i] .field; 其中源和目的地中的两个字段都是双精度或长数。
将鼠标悬停在源上会显示正确计算的值。在执行语句之前将鼠标悬停在目标上,表明它已正确初始化为零。执行语句后,目标包含不同的值,例如36.3468变为0.00104800000000122891,6变为10等
这很奇怪。也许有一个结构元素错位,但不会在其他地方显示为警告?也许我正在踩着内存(仅限32位版本!?),但是在踩到作业后,这个值显然不应该是正确的吗?有一段时间没有进入机器代码并且不了解x86 / x86_64程序集,我是否必须这样做以查看执行该分配的代码实际上在做什么?
以下是其中一条似乎无法正确执行的行以及64位和32位版本中的反汇编,按顺序:
destination[i].field = source[i].field;
000007FEEF6B4DD3 movsxd rax,dword ptr [i]
000007FEEF6B4DDB imul rax,rax,4A68h
000007FEEF6B4DE2 movsxd rcx,dword ptr [i]
000007FEEF6B4DEA imul rcx,rcx,30h
000007FEEF6B4DEE mov rdx,qword ptr [destination]
000007FEEF6B4DF3 mov r8,qword ptr [source]
000007FEEF6B4DF8 movsd xmm0,mmword ptr [r8+rax+4A40h]
000007FEEF6B4E02 movsd mmword ptr [rdx+rcx+8],xmm0
destination[i].field = source[i].field;
09E64361 mov eax,dword ptr [i]
09E64364 imul eax,eax,4A38h
09E6436A mov ecx,dword ptr [i]
09E6436D imul ecx,ecx,2Ch
09E64370 mov edx,dword ptr [destination]
09E64373 mov esi,dword ptr [source]
09E64376 fld qword ptr [esi+eax+4A10h]
09E6437D fstp qword ptr [edx+ecx+4]
如果我在64位版本中跳过该行,VS会向我显示destination [i] .field的正确值,但不会在32位版本中。看起来结构在不同的版本中有不同的大小,因此在最后一个赋值中有不同的偏移量和4对8个字节,但是不应该在那个时候VS向我显示正确的值?
如果我跳过32位版本的fld指令,我可以看到st0加载了错误的值,即没有为source [i] .field显示的内容,对于i = 0,eax = 0, esi = source,因此可能是4A10h偏移在代码中是错误的和/或不同的计算,以及VS使用什么来向我显示该值。这怎么可能?