2012-08-06 102 views
3

在我看來,MSVS忽略了我的函數上的__stdcall指令。我正在手動清理堆棧,但編譯器仍然在每個CALL後附加ADD ESP指令。編譯器忽略__stdcall

這是我的聲明功能:

extern "C" void * __stdcall core_call(int addr, ...); 
#define function(...) (DWORD WINAPI) core_call(12345, __VA_ARGS__) 
return function("Hello", 789); 

這是輸出的樣子: http://vs712.server4u.cz/msvs.png

我用箭頭標記冗餘ADD指令,MSVS每個之後自動追加打電話,儘管事實上,清除堆棧是一個被調用者的責任(參考:http://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions),這導致我的程序崩潰。如果我手動將ADD指令替換爲NOPs,程序將按預期工作。所以,我的問題是...有沒有辦法強制編譯器停止添加這些指令?

謝謝。

回答

5

問題是在這裏:, ...)

參數個數不定的函數不能是__stdcall

__stdcall函數必須從堆棧中刪除所有堆棧參數,但它們不能提前知道它們將作爲參數接收多少東西。

這同樣適用於__fastcall函數。

可變參數數量的函數唯一適用的調用約定是__cdecl,其中調用者必須在調用後刪除堆棧參數。儘管您的請求使用__stdcall,編譯器仍然使用這種方式。

+0

您是否知道編譯器忽略顯式請求的調用約定時是否生成警告? – 2012-08-06 19:28:48

+0

感謝您的回覆。我花了幾個小時來調試代碼,而我發現問題出在哪裏。編譯器顯示了一些警告,但我不清楚爲什麼它忽略了我明確指定的內容。 但是,有沒有一些解決方法如何做到這一點?我甚至嘗試寫一些內聯程序集來傳遞參數到函數core_call,但是我沒有成功。 – Peter 2012-08-06 19:41:11

+0

嘗試類似[this](http://pastebin.com/Fntqb1j2),使用函數指針。 – 2012-08-06 20:20:14