2011-09-14 48 views
3

我正在處理一個大小受限的項目,所以我不想鏈接到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 
    } 
} 
+0

你正在使用什麼指令或功能?我仍然可以通過擺弄設置來構建VS2010的「微小」可執行文件。 – Luke

+0

@Luke:我不想再重新發布msvcrt100.dll。我可以通過鏈接到系統的msvcrt.dll(因爲tell()函數失敗而無法工作)或鏈接到靜態msvcrt.lib來增加可執行文件大小達200 KB,從而避免這種情況。上面的符號是由簡單的float生成的,用於長轉換和math.h函數。 – maep

回答

3

這是我不得不從默認的Win32項目在VS2010改變什麼:

調試

  • C/C++ - 代碼生成 - 基本運行時檢查=默認
  • C/C++ - 代碼生成 - 運行時庫=多線程調試(/ MTd)
  • 鏈接器 - 輸入 - 忽略特定的默認庫= libcmtd。LIB

發佈

  • 一般 - 整體規劃設計優化=沒有整體規劃設計優化
  • C/C++ - 優化 - 整個程序優化=無
  • C/C++ - 代碼生成 - 運行時庫=多線程(/ MT)
  • 鏈接器 - 輸入 - 忽略特定的默認庫= libcmt.lib

不得不做一些事情來處理浮點東西:

  • C/C++ - 命令行=/QIfist(也SetFloatingPointRoundingToTruncate;見下面的鏈接)
  • extern「C」int _fltused = 1; //一個全球性的編譯器定義加載某些浮點東西

我讀到一篇interesting blog post來打造簡約方案在VS,我發現一些這方面的信息;如果你仍然有問題,可能會有額外的提示。

通過所有這些調整,我可以編譯和鏈接一個程序,該程序將float轉換爲long並調用一些pow()函數。發佈版本只有3.5 KB,並且包含嵌入式清單。

2

我也參與過使用Visual Studio(.NET 2003)編譯而不需要CRT的項目。 VS的更新版本更難以使用,我們發現它不值得黑客運行。

相反,您可能需要查看minicrt/lictiny。谷歌在奧馬哈使用這個 - 谷歌和谷歌地球的自動更新。

您也可能想嘗試MinGW工具鏈,因爲它可以鏈接到MSVCRT.DLL,它是一個系統組件,不需要由應用程序分發。