__declspec(naked) double __cdecl exp(double x) { __asm { //Prologue de la fonction. push ebp; mov ebp, esp; sub esp, __LOCAL_SIZE; //Le calcul en lui même. FLD x; PUSH x FLDL2E; PUSH log2(e) FMULP ST(1),ST(0); ST(1)=ST(1)*ST(0) POP //ST(0) contient x*log2(e) FLD1; PUSH 1 FLD ST(1); PUSH ST(1) //On pousse ST(1). Cette valeur est donc dans ST(0) et ST(2) FPREM; ST(0)=ST(0) mod ST(1) //En fait, on mets dans ST(0) la partie fractionnaire de ST(0) F2XM1; ST(0)=2^ST(0)-1 FADDP ST(1),ST(0); ST(1)=ST(0)+ST(1) POP //parfait 1 était encore dans ST(1) FSCALE; ST(0)=ST(0)*2^(int)ST(1) //On se souvient que ST(1)=x*log2(e) FXCH; swap ST(0) et ST(1) //Je n'aime pas cette ligne, mais je n'ais pas réussi à faire mieux. FFREE ST(0); FINCSTP; POP //Epilogue de la fonction. mov esp, ebp; pop ebp; ret; Le résultat est dans ST(0) } } /* Pour le principe, on calcul exp(x) : y=x*log2(e) ou log2 est le logarithme en base 2. t1=(frac)y t1 est la partie fractionnaire de y t2=(int)y t2 est la partie entière de y c'est à dire : y=t1+t2=x*log2(e) s1=2^t1-1 s2=s1+1 donc s2=2^t1 s3=s2*2^t2 donc s3=2^t1*2^t2=2^(t1+t2)=2^y=2^(x*log2(e))=(2^log2(e))^x=e^x On a bien : s3=exp(x). */ //Pour en faire un truc inline (pas une vrai fonction) il faut garder juste le corp : __asm { FLD x; PUSH x FLDL2E; PUSH log2(e) FMULP ST(1),ST(0); ST(1)=ST(1)*ST(0) POP FLD1; PUSH 1 FLD ST(1); PUSH ST(1) FPREM; ST(0)=ST(0) mod ST(1) F2XM1; ST(0)=2^ST(0)-1 FADDP ST(1),ST(0); ST(1)=ST(0)+ST(1) POP (parfait 1 était encore dans ST(1)) FSCALE; ST(0)=ST(0)*2^(int)ST(1) //On se souvient que ST(1)=x*log2(e) FXCH; swap ST(0) et ST(1) FFREE ST(0); FINCSTP; POP FSTP y; } //Là, ce bloque enregistre dans y la valeur exp(x). //Il faut que x et y existe dans la portée en question.