我在嘗試將32位產品轉換爲64位產品時遇到問題。我使用的是Visual Studio 2008,代碼是C和C++。我希望任何人都能看到以下兩行代碼,一行來自C源文件,另一行來自C++源文件。這兩個文件都包含在DLL中。我還包括兩行代碼的反彙編。C和C++編譯器的問題
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++?對於我們所知道的這是編譯器中的一個代碼問題,此後已經修復。 : - ] – ildjarn
這些調試版本或優化?也許你可以顯示任何'pCM'指向的結構? –
另外,'pCM-> pSecAccInfo-> spUserID'中有兩個重定向似乎很奇怪,但彙編代碼似乎只執行一個(在每個示例中)。例如,在你的第一個彙編代碼片段中,第一次加載到'rcx'大概是從本地堆棧變量加載'pCM'到寄存器,然後'rcx'的下一個加載將加載'pSecAccInfo' - 但是'rcx'應該有在調用memcpy()之前,在'rcx'中調用'spUserID'。有可能通過優化,第一個負載實際上是'pSecAccInfo'(但你說你確認它是'pCM')。 –