Я работаю над проектом с ограничениями размера, поэтому я не хочу ссылаться на среду выполнения Visual Studio C.Я делаю это с помощью Static Runtime (/ MT) и флагов / NODEFAULTLIB: LIBCMT.Я выяснил большинство вещей, проверив источники времени выполнения, которые поставляются с VS.Однако компилятор по-прежнему генерирует некоторые неразрешенные внешние символы:
_chkstk
: генерируется для проверки стека функции размером более 4 КБ.Могу ли я отключить это или предоставить фиктивную функцию?
__libm_sse2_pow
и другие вызовы SSE: я могу избежать этого, отключив генерацию кода SSE, но я хотел бы иметь их, если это возможно.Эти символы, похоже, взяты из библиотеки Intel (libmmd.lib?).В любом случае, почему эта часть среды выполнения C?
_ftol2_sse
: конвертировать float в long.Я все еще получаю это, несмотря на отключение генерации кода SSE.
_CIpow
: еще одна функция Пау.Интересно, почему компилятор генерирует это вместо SEE.
Существуют ли какие-либо настройки, макросы препроцессора или прагмы, управляющие генерацией этого кода?Я также пытался использовать msvcrt.lib из Visual Studio 6.0 SP6, но некоторые функции, которые я использую, не работают с компилятором VS2010.
edit:
_chkstk
можно отключить, поставив #pragma check_stack(off)
перед соответствующими функциями. можно найти в источнике CRT, поставляемом с Visual Studio.
_CIpow
немного сложнее.Это внутренняя версия pow, которая использует специальное соглашение о вызовах.Я не нашел способа выключить его, поэтому я сам переопределил его на ассемблере.Я получил некоторое вдохновение здесь: Как: Pow (настоящий, настоящий) в 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
}
}