我正在處理一個大小受限的項目,所以我不想鏈接到Visual Studio的C運行時。我使用Static Runtime(/ MT)和/ NODEFAULTLIB:LIBCMT標誌來完成此操作。通過檢查VS附帶的運行時間源,我得到了大部分東西。但是,編譯器仍會生成一些無法解析的外部符號:未使用C運行時與VS2010鏈接時未解析的符號
_chkstk
:生成以檢查大於4k的函數的堆棧。我可以關閉它或提供虛擬功能嗎?
__libm_sse2_pow
和其他SSE調用:我可以通過關閉SSE代碼生成來避免這些,但我希望如果可能的話可以使用它們。這些符號似乎來自Intel lib(libmmd.lib?)。無論如何,爲什麼這部分C運行時?
_ftol2_sse
:將float轉換爲long。儘管關閉了SSE代碼生成,我仍然可以得到這個結果。
_CIpow
:另一個pow函數。我想知道爲什麼編譯器生成這個而不是SEE。
是否有任何設置,預處理宏或用於控制代碼生成的編譯指示?我也嘗試從Visual Studio 6.0 SP6使用msvcrt.lib,但我使用的一些函數不能與VS2010編譯器一起使用。
編輯:
_chkstk
可以通過將
。#pragma check_stack(off)
中的相關功能前關閉。可以在Visual Studio附帶的CRT源中找到
_CIpow
有點困難。這是pow的內在版本,它使用特殊的調用約定。我發現沒有辦法關掉它,所以我最終用自己的彙編語言重新實現了它。我在這裏得到了一些啓發:How to: pow(real, real) in x86。我有一段時間沒有完成彙編程序,這是我第一次在x86上完成。我沒有對所有情況進行測試,所以沒有保證!如果您有任何改進建議或發現錯誤,請告訴我。
void __cdecl _CIpow(void)
{
// implementation of pow function as 2^(y*log2(x)). this is the
// intrinsic version so base and exponent are already on the fpu
// stack ST0 and ST1. the result is pushed to ST0.
// note that earlier rounding for fist was set to truncate
int temp;
__asm {
// values are repushed, cause fyl2x will overwrite them both
fld st(0) // push ST0 to ST0
fld st(2) // push ST2 (ex ST1) to ST0
fyl2x // ST1 = ST1*log2(ST0), pop ST0
fist temp // assumes truncate rouning
fisub temp // S0 = S0 - temp
f2xm1 // ST0 = (2^ST0)-1
fld1 // push 1 to ST0
faddp st(1),st(0) // ST1 = ST1 + ST0, pop ST0
fild temp // push temp to ST0
fxch // swap ST0 and ST1
fscale // ST0 = inc exp of ST0 by ST1
fxch // put reslut in ST1
fstp st(0) // pop ST0
}
}
你正在使用什麼指令或功能?我仍然可以通過擺弄設置來構建VS2010的「微小」可執行文件。 – Luke
@Luke:我不想再重新發布msvcrt100.dll。我可以通過鏈接到系統的msvcrt.dll(因爲tell()函數失敗而無法工作)或鏈接到靜態msvcrt.lib來增加可執行文件大小達200 KB,從而避免這種情況。上面的符號是由簡單的float生成的,用於長轉換和math.h函數。 – maep