【发布时间】:2012-12-05 00:08:30
【问题描述】:
我在尝试将 32 位产品转换为 64 位产品时遇到问题。我使用的是 Visual Studio 2008,代码是 C 和 C++。我希望任何人都可以查看以下两行代码,一行来自 C 源文件,另一行来自 C++ 源文件。这两个文件都包含在 DLL 中。我还包括了两行代码的反汇编。
ewxlcom.c
memcpy(pCM->pSecAccInfo->spUserID,userSecurityInfo.spUserID,
sizeof(UserID));
000000000EF33BB9 mov r8d,80h
000000000EF33BBF mov rdx,qword ptr [rsp+828h]
000000000EF33BC7 mov rcx,qword ptr [rsp+1F8h]
000000000EF33BCF mov rcx,qword ptr [rcx+0BDEh]
000000000EF33BD6 call memcpy (0EF40352h)
tcputil.cpp
memcpy(serv_temp+INIT_MSG_USERID_OFFSET, pCM->pSecAccInfo->spUserID, INIT_MSG_USERID_LEN);
000000000EF3B8E6 lea rcx,[rsp+67h]
000000000EF3B8EB mov r8d,80h
000000000EF3B8F1 mov rdx,qword ptr [rsp+3B0h]
000000000EF3B8F9 mov rdx,qword ptr [rdx+0CBEh]
000000000EF3B900 call memcpy (0EF40352h)
如您所见,第一行将一些字节复制到pCM->pSecAccInfo->spUserID 指向的内存中。第二行将这些相同的字节复制到内存中的另一个位置。 ASM memcpy 将字节从寄存器rdx 指向的内存复制到寄存器rcx 指向的内存。所以在第一行中,一个值被移入寄存器rcx。我已经验证指向pCM。然后将rcx + 0BDEh 指向的值复制到rcx 中。并调用了memcpy。这行得通。
但稍后在第二行将一个值加载到寄存器rdx。我已经验证这也指向与第一行相同的pCM。然后它加载驻留在内存中的指针,该指针与pCM (rdx) 偏移0CBEh。那段内存全为零,所以memcpy 崩溃了。
问题是为什么编译器会为同一个源变量生成不同的代码。我认为这是一个对齐问题。这是C文件和C++文件之间的区别吗? VS 是否对 C 和 C++ 使用相同的编译器?还有什么我应该看的吗?
任何帮助将不胜感激。
【问题讨论】:
-
您是否尝试过使用较新版本的 VC++?据我们所知,这是编译器中的一个代码生成问题,此后已得到修复。 :-]
-
这些是调试版本还是优化?也许您可以显示
pCM指向的任何结构? -
另外,
pCM->pSecAccInfo->spUserID中有两个重定向似乎很奇怪,但汇编代码似乎只执行一个(在每个示例中)。例如,在您的第一个程序集 sn-p 中,第一次加载到rcx大概是将pCM从本地堆栈变量加载到寄存器中,然后rcx的下一次加载将加载pSecAccInfo- 但rcx在调用memcpy()之前,应该在rcx中有spUserID。有可能通过优化,第一次加载实际上是pSecAccInfo(但你说你验证了它是pCM)。
标签: c++ c visual-studio-2008 visual-c++