Привет всем! Я не забыл за библиотеку! Эта темка - мое видение оной! По делу - я вот решил FPU освоить, процедурка в m32lib мне не приглянулась - вот, поэкспериментировал: потестируйте, если кому не лень. Замечания приветствуются, "ух ты" и "фу" - нет Код (Text): .data align 4 int10 dd 10 ten_1 dt 1.0e0001,1.0e0002,1.0e0003,1.0e0004 dt 1.0e0005,1.0e0006,1.0e0007,1.0e0008 dt 1.0e0009,1.0e0010,1.0e0011,1.0e0012 dt 1.0e0013,1.0e0014,1.0e0015 ten_16 dt 1.0e0016,1.0e0032,1.0e0048,1.0e0064 dt 1.0e0080,1.0e0096,1.0e0112,1.0e0128 dt 1.0e0144,1.0e0160,1.0e0176,1.0e0192 dt 1.0e0208,1.0e0224,1.0e0240 ten_256 dt 1.0e0256,1.0e0512,1.0e0768,1.0e1024 dt 1.0e1280,1.0e1536,1.0e1792,1.0e2048 dt 1.0e2304,1.0e2560,1.0e2816,1.0e3072 dt 1.0e3328,1.0e3584,1.0e3840,1.0e4096 dt 1.0e4352,1.0e4608,1.0e4864 .code a2f proc uses esi edi snum:DWORD local num: DWORD local exp: DWORD local sign: DWORD ;----------------------------- ; ver. 3.1 ;----------------------------- ; вход: snum - указатель на текстовый буфер с числом ; выход: еах - указатель на первый нераспознанный символ, ; или 0, если ошибка ; zf - 0, если не ошибка ; st(0) - введенное число (если не ошибка) ; есх - ? ;----------------------------- ; преобразует текстовую строку ; в формате [+|-]999[.[999]][Е[+|-]999] в вещественное число. ; число цифр мантиссы и порядка не проверяется, но переполнение ; результата проверяется. ; введенное число возвращается в st(0). ; при ошибке указатель стека FPU восстанавливается. ; вызывающая процедура может проверить нераспознанный символ ; на допустимый разделитель. ;----------------------------- ;----------------------------- загрузка исходных значений mov esi,snum xor eax,eax mov ecx,eax mov edi,eax mov sign,eax fldz ;----------------------------- проверка на знак числа lodsb cmp al,"+" je a2i_loop cmp al,"-" jne a2i_after_sign inc sign ;----------------------------- ввод мантиссы в st(0) a2i_loop: lodsb a2i_after_sign: cmp al,"." je a2i_dot cmp al,"0" jc a2i_ex cmp al,"9"+1 jnc a2i_ex sub al,"0" mov num,eax fimul int10 fiadd num inc edi jmp a2i_loop a2i_dot_good: mov ecx,esi jmp a2i_loop a2i_dot: jecxz a2i_dot_good ;------ иначе -> вторая точка в строке a2i_err: ffree st(0) fincstp xor eax,eax ; <- неявная установка ZF ret a2i_ex: ;----------------------------- завершающий код ввода мантиссы test edi,edi jz a2i_err jecxz @F ;----------------------------- преобразование позиции точки в порядок sub ecx,esi inc ecx @@: mov exp,ecx cmp sign,0 je @F fchs @@: ;----------------------------- конец ввода мантиссы cmp al,"E" je a2f_e cmp al,"e" je a2f_e a2f_ex_good: ;----------------------------- применение порядка mov eax,exp test eax,eax jz p10_ex_z pushf jns @F neg eax ;---------------- подгонка на случай большого числа цифр после точки p10_exp_chk: cmp eax,4932 jl @F fld ten_256 fdiv sub eax,256 jmp p10_exp_chk @@: mov edi,eax fld1 and eax,0Fh jz @F add eax,eax fld ten_1[eax+eax*4-10] fmul @@: mov eax,edi shr al,4 and eax,0Fh jz @F add eax,eax fld ten_16[eax+eax*4-10] fmul @@: mov eax,edi mov al,ah and eax,01Fh jz @F add eax,eax fld ten_256[eax+eax*4-10] fmul @@: popf js p10_ex_d fmul jmp p10_ex_z p10_ex_d: fdiv fstsw word ptr num test word ptr num,19h jnz a2i_err ;----------------------------- нормальный выход p10_ex_z: mov eax,esi dec eax ; <- неявный сброс ZF ret ;----------------------------- ввод порядка a2f_e: ;----------------------------- подготовка регистров push edx xor edi,edi xor ecx,ecx mov sign,edi ;----------------------------- поехали lodsb ;----------------------------- проверка на знак порядка cmp al,"+" je a2f_e_loop cmp al,"-" jne a2f_e_after_sign inc sign ;----------------------------- ввод числа порядка a2f_e_loop: lodsb a2f_e_after_sign: sub al,"0" jc a2f_e_ex cmp al,10 jnc a2f_e_ex xchg ecx,eax mul int10 add eax,ecx cmp eax,4932 ; не превышает ли значение порядка 4932 ? jg a2f_e_fail xchg ecx,eax inc edi jmp a2f_e_loop a2f_e_ex: ;----------------------------- введена ли хоть одна цифра? pop edx test edi,edi jz a2i_err cmp sign,0 je @F neg ecx @@: ;----------------------------- коррекция порядка add exp,ecx jmp a2f_ex_good ;----------------------------- порядок некорректен - откат a2f_e_fail: pop edx jmp a2i_err a2f endp пример вызова: Код (Text): ... push offset text_buffer_containing_number call a2f jz error_input_1 ; ошибка формата mov al,byte ptr [eax] test al,al jnz error_input_2 ; неверный разделитель ... канэшна, credits: спасибо всем за все хорошее 01>забыл за .data? 02>значительно переделал (если кто ваще заметил 03> --//-- 04>не удержался - микроизменение - теперь число значащих цифр мантиссы просто не должно превышать 4931... и все. след. число прохавано: test_ db "13225468798796464654626576565768765464647" db "65472679872687626786826746872646846265455" db "32547265424564265465465465254642645646265" db "65276842684628746268426872687462464682468" db "." db "62874684246268435587387597624648942684862" db "E-000000000000000000000000000000000004777" db 0 ; ST0 valid 1.3225468798796464650e-4614 а винкалькулятор его не съел
Все! надаела! дальше улучшать не хочу, разве если только явная ошибка будет - исправлю. кушает вроде все от 1е4932 до 1е-4932. проверял на прилепленной проге под олей. не пишите только 257 цифр после запятой с порядком -49хх - может не понять. (меньше - должна, по идее). 256403655__fpu_lab.zip