2015-01-26 77 views
1

我在使用virtualalloc時有一些奇怪的行爲。我在C++,Visual Studio 2010中VirtualAlloc的順序似乎很重要(C++)

我有兩件事情我想分配,和我使用的VirtualAlloc(我有我的理由,無關的問題)

1 - 空間舉行的x86彙編代碼緩衝
2 - 空間來保存的x86代碼要

在我的代碼中的數據結構我做:

thread_data_t * p_data = (thread_data_t*)VirtualAlloc(NULL, sizeof(thread_data_t), MEM_COMMIT, PAGE_READWRITE); 
//set up all the values in the structure 
unsigned char* p_function = (unsigned char*)VirtualAlloc(NULL, sizeof(buffer), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
memcpy(p_function, buffer, sizeof(buffer)); 
CreateThread(0, (LPTHREAD_START_ROUTINE)p_function, p_data, 0, NULL); 
在調試模式

:做工精細
在RELEASE模式下:啓動線程接收一個空作爲其輸入數據。通過調試進行驗證,當我調用createThread時,指針正確

如果我切換VirtualAlloc的周圍,以便在數據空間之前分配函數空間,那麼DEBUG和RELEASE模式都可以正常工作。

任何想法爲什麼?我已驗證我的所有VS版本設置在DEBUG/RELEASE之間是相同的

回答

4

將彙編代碼複製到內存緩衝區後,不能直接跳到該緩衝區。你需要刷新CPU緩存等,否則它將無法工作。您可以使用FlushInstructionCache來執行此操作。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms679350%28v=vs.85%29.aspx

很難說究竟爲什麼重新排序的撥款會解決這個問題,但如果你複製的指令到他們的緩衝區,然後跳進緩衝區之前做了很多工作,這將有可能提高「逃避它」的機率,因爲CPU緩存會有更多機會被其他方式刷新。

+0

順便說一句我把我的鏈接換成了更好的參考。舊的鏈接更多的是關於檢測案件而不是解決案件。 – StilesCrisis 2015-01-26 21:27:19

+0

你是否也可以放回你的另一個鏈接?所以我可以閱讀有關檢測並解決它?謝謝 ! – 2015-01-26 21:35:26

+0

同樣在閱讀鏈接時,我看到「在x86或x64 CPU架構上不需要FlushInstructionCache,因爲它們具有透明緩存。」 – 2015-01-26 21:36:11