Интересует есть ли у кого, оптимизированная версия процедуры FpuXexpY из fpulib (masm) по размеру ? Вообще задача состоит в том что бы сделать X^Y ( где X,Y - double ) средствами FPU. Думал считать по известной формуле : X^Y = 1+ F2XM1(FYL2X(Y,X)) , но что то оно не так, не пойму что упускаю.
Сильно тупанул, заработался видимо Прикладываю рабочий код (может кому то и пригодиться) , теперь интересует оптимизация. Код (Text): ; Вычисляет формулу : (3/4) ^ ((x^2-x-1)/x) - 9/16 ; средствами FPU format PE console entry OEP include 'win32a.inc' ;====================================== section '.data' data readable writeable ;====================================== hello_msg db 'Press input, x = ',0 x_is_zero db 'Sorry, x not must be zero!',13,10,0 f_x_out db 'f(x) = %lf',13,10,0 h_c_out dd 0h h_c_in dd 0h tmp dd 0h floatX dq ? _3 dq 3.0 _4 dq 4.0 _9 dq 9.0 _16 dq 16.0 f_x dq ? intput_buffer db 255 dup (0) output_buffer db 255 dup (0) ;======================================= section '.code' code readable executable ;======================================= OEP: finit ; Включаем FPU invoke GetStdHandle,STD_OUTPUT_HANDLE ; Получаем хендл вывода консоли mov [h_c_out],eax ; и сохраняем его в переменной invoke GetStdHandle,STD_INPUT_HANDLE ; Так же поступаем и с хендлом mov [h_c_in],eax ; ввода консоли. invoke lstrlen,hello_msg ; Определяем длинну строки hello_msg invoke WriteConsole,[h_c_out],hello_msg,eax, tmp,NULL ; Выводим её invoke ReadConsole,[h_c_in],intput_buffer,255,tmp,NULL ; Ждём окончания ввода ;invoke MessageBox,0,intput_buffer,intput_buffer,0 cinvoke atof, intput_buffer ; atof ф-я из msvcrt.dll ( Ansi String to Float ) pushad ; Сохраняем все регистры и флаги CPU ; Теперь в ST(0) находиться X ftst ; теперь проверим X на ноль fstsw ax ; сохраняем слово состояния регистра swr в регистр ax fwait sahf ; записываем содержимое AH в младший байт регистра EFLAGS je is_zero ; теперь можем провести сравнение ja : ST0 > 0 ; jb : ST0 < 0 ; je : ST0 == 0 fld ST0 ; Теперь в ST(0) и ST(1) содержиться наш X fmul ST0,ST1 ; Теперь в ST(0) = x^2 fsub ST0,ST1 ; Теперь в ST(0) = x^2 - x fld1 ; Теперь в ST(0) = 1 , ST(1) = x^2 - x fsub ST1,ST0 ; ST(1) = x^2 - x - 1 fxch ST2 fdiv ST1,ST0 ; ST(1) = ( x^2 - x - 1 ) / x fxch ST1 ; ST(0) = ( x^2 - x - 1 ) / x fld qword[_3] fld qword[_4] fdiv ST1,ST0 ; ST(1) = 3/4 fxch ST2 fxch ST1 fyl2x f2xm1 fld1 fadd ST1,ST0 ; ST(1) = (3/4) ^ ( ( x^2 - x - 1 ) / x ) fld qword[_9] fld qword[_16] fdiv ST1,ST0 ; ST(1) = 9/16 fxch ST3 fsub ST0,ST1 fstp qword[f_x] ; сохраняем переменную и очищаем ST(0) popad ; Восстанавливаем все регистры и флаги CPU push dword [f_x+4] push dword [f_x] push f_x_out call [printf] add esp,4*3 ; Выводим наш результат f_x invoke ReadConsole,[h_c_in],intput_buffer,1,tmp,NULL ; ждём нажатия клавишы и завершаемся jmp @exit is_zero: invoke lstrlen,x_is_zero invoke WriteConsole,[h_c_out],x_is_zero,eax, tmp,NULL @exit: stdcall [ExitProcess],0 ; Таблица импорта ф-ий section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ user32, 'user32.dll',\ msvcrt, 'msvcrt.dll' import msvcrt,\ atof,'atof',\ printf,'printf' include '\api\kernel32.inc' include '\api\user32.inc'
Видимо, да, т.к. вычислять константы 3/4 и 9/16, вместо того чтобы сразу задать 0.75 и 0.5625 - это "супер-оптимизация"