Add COFF libraries "utils.obj" atof,ftoa,random

support for exponent, high accuracy, not normalized form of writing

git-svn-id: svn://kolibrios.org@4721 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Akyltist 2014-03-31 05:57:30 +00:00
parent 87aa62f216
commit 9b11245e08
6 changed files with 793 additions and 0 deletions

View File

@ -0,0 +1,300 @@
;-----------------------------------------------------------------------------+
; ”ã­ªæ¨ï ¯à¥®¡à §®¢ ­¨ï áâப¨ ¢ ¢¥é¥á⢥­­®¥ ç¨á«® [ by ManHunter / PCL ] |
;-----------------------------------------------------------------------------|
; <EFBFBD> à ¬¥âàë: |
; lpStr - 㪠§ â¥«ì ­  ¨á室­ãî áâப㠢 ä®à¬ â¥ ASCIIZ |
; lpResult - 㪠§ â¥«ì ­  ¯¥à¥¬¥­­ãî-¯à¨¥¬­¨ª §­ ç¥­¨ï |
; <EFBFBD>  ¢ë室¥: |
; EAX = 1 - áâப  ãᯥ譮 ¯à¥®¡à §®¢ ­  |
; EAX = 0 - áâப  ­¥ ¬®¦¥â ¡ëâì ¯à¥®¡à §®¢ ­  ¢ ç¨á«® |
;-----------------------------------------------------------------------------+
proc string2float lpStr:DWORD, lpResult:DWORD
; ‹®ª «ì­ë¥ ¯¥à¥¬¥­­ë¥
locals
dot dd ? ; “ª § â¥«ì ­  ¤à®¡­ãî ç áâì
exp dd ? ; “ª § â¥«ì ­  íªá¯®­¥­âã
digit dd ? ; –¨äà 
endl
pusha
; <EFBFBD>஢¥àª  áâப¨ ­  ¢ «¨¤­®áâì
mov [digit],1
mov [exp],0
mov [dot],0
mov esi,[lpStr]
; Œ¨­ãá ¨«¨ ¯«îá ¬®¦¥â ¡ëâì ⮫쪮 ¢ ­ ç «¥
cmp byte [esi],'-'
je @f
cmp byte [esi],'+'
jne .loc_chk_loop
@@:
inc esi
; <EFBFBD>®á«¥ §­ ª  ­¥ ¬®¦¥â ¡ëâì ­ã«ï
cmp byte [esi],0
je .loc_chk_error
.loc_chk_loop:
; áâப¥ ¤®«¦­ë ¡ëâì æ¨äà, íªá¯®­¥­â  ¨ ­¥ ¡®«¥¥ ®¤­®© â®çª¨
lodsb
or al,al
jz .loc_chk_complete
cmp al,'e'
je .loc_chk_exp
cmp al,'E'
je .loc_chk_exp
cmp al,'.'
je .loc_chk_dot
cmp al,'0'
jb .loc_chk_error
cmp al,'9'
ja .loc_chk_error
jmp .loc_chk_loop
.loc_chk_dot:
; ’®çª  ¢ áâப¥ 㦥 ¥áâì?
cmp [dot],0
; ‘âப  ¨¬¥¥â ­¥ª®à४â­ë© ä®à¬ â
jne .loc_chk_error
; <EFBFBD>ªá¯®­¥­â  㦥 ¥áâì?
cmp [exp],0
; ‘âப  ¨¬¥¥â ­¥ª®à४â­ë© ä®à¬ â
jne .loc_chk_error
; “ª § â¥«ì ­  ¤à®¡­ãî ç áâì
mov [dot],esi
jmp .loc_chk_loop
.loc_chk_exp:
; <EFBFBD>ªá¯®­¥­â  㦥 ¥áâì?
cmp [exp],0
; ‘âப  ¨¬¥¥â ­¥ª®à४â­ë© ä®à¬ â
jne .loc_chk_error
; “ª § â¥«ì ­  ­ ç «® íªá¯®­¥­âë
mov [exp],esi
; ‘ࠧ㠯®á«¥ íªá¯®­¥­âë ­¥ ¬®¦¥â ¡ëâì ­ã«ï
cmp byte [esi],0
je .loc_chk_error
; <EFBFBD>®á«¥ íªá¯®­¥­âë ¬®¦¥â ¡ëâì §­ ª
cmp byte [esi],'-'
je @f
cmp byte [esi],'+'
jne .loc_chk_loop
@@:
inc esi
; ‘ࠧ㠯®á«¥ ¬¨­ãá  ­¥ ¬®¦¥â ¡ëâì ­ã«ï
cmp byte [esi],0
je .loc_chk_error
; <EFBFBD>஢¥à¨âì á«¥¤ãî騩 ᨬ¢®«
jmp .loc_chk_loop
.loc_chk_error:
; ‘âப  ­¥ ï¥âáï ç¨á«®¬
mov [digit],0
jmp .loc_ret
.loc_chk_complete:
; ˆ­¨æ¨ «¨§ æ¨ï ᮯà®æ¥áá®à 
finit
; <EFBFBD> ç «ì­®¥ §­ ç¥­¨¥ ç¨á« 
fldz
; Œ­®¦¨â¥«ì ¨ ¤¥«¨â¥«ì
mov [digit],10
fild dword [digit]
; ‡ ¯¨áì §­ ç¥­¨© ¤® § ¯ï⮩
mov esi,[lpStr]
; ­ ç «¥ áâப¨ ¬¨­ãá?
cmp byte [esi],'-'
je @f
cmp byte [esi],'+'
jne .loc_before_dot
@@:
inc esi
; <EFBFBD>८¡à §®¢ ­¨¥ ç¨á«  ¤® § ¯ï⮩
.loc_before_dot:
lodsb
; Š®­¥æ áâப¨?
or al,al
jz .loc_complete
cmp al,'.'
je .loc_complete_before_dot
cmp al,'e'
je .loc_exp
cmp al,'E'
je .loc_exp
; Žç¥à¥¤­ ï æ¨äà 
sub al,'0'
movzx eax,al
mov [digit],eax
; ‡ ¯¨á âì
fild dword [digit]
fxch st2
fmul st0,st1
fxch st2
fadd st2,st0
ffree st0 ; <EFBFBD>®ç¨áâ¨âì á⥪
fincstp
jmp .loc_before_dot
; <EFBFBD>८¡à §®¢ ­¨¥ ¤à®¡­®© ç á⨠ç¨á« 
.loc_complete_before_dot:
; „஡­ ï ç áâì ¥áâì?
cmp [dot],0
je .loc_complete_after_dot
; <EFBFBD>ªá¯®­¥­â  ¥áâì?
cmp [exp],0
je @f
; “ª § â¥«ì ­  ­ ç «® íªá¯®­¥­âë
mov esi,[exp]
jmp .loc_start_after_dot
@@:
; ˆ­ ç¥ ¯¥à¥­¥á⨠㪠§ â¥«ì ­  ª®­¥æ áâப¨
xor ecx,ecx
dec ecx
xor eax,eax
mov edi,esi
repne scasb
mov esi,edi
.loc_start_after_dot:
std
dec esi
dec esi
; „஡­ ï ç áâì
fldz
fxch st1
.loc_after_dot:
lodsb
; Š®­¥æ ¤à®¡­®© ç áâ¨?
cmp al,'.'
je .loc_complete_after_dot
; Žç¥à¥¤­ ï æ¨äà 
sub al,'0'
movzx eax,al
mov [digit],eax
; ‡ ¯¨á âì
fild dword [digit]
fadd st2,st0
fxch st2
fdiv st0,st1
fxch st2
ffree st0 ; <EFBFBD>®ç¨áâ¨âì á⥪
fincstp
jmp .loc_after_dot
.loc_complete_after_dot:
; ‘¡à®á¨âì ä« £ ­ ¯à ¢«¥­¨ï
cld
ffree st0 ; <EFBFBD>®ç¨áâ¨âì á⥪
fincstp
; ‘«®¦¨âì ¤à®¡­ãî ¨ 楫ãî ç áâì
fadd st1,st0
.loc_exp:
; <EFBFBD>ªá¯®­¥­â  ¥áâì?
cmp [exp],0
je .loc_complete
; <EFBFBD>®«ãç¨âì §­ ç¥­¨¥ íªá¯®­¥­âë
xor ecx,ecx
mov esi,[exp]
; ­ ç «¥ áâப¨ ¬¨­ãá?
cmp byte [esi],'-'
je @f
cmp byte [esi],'+'
jne .loc_start_exp
@@:
inc esi
.loc_start_exp:
lodsb
or al,al
jz .loc_end_exp
sub al,'0'
movzx eax,al
imul ecx,10
add ecx,eax
jmp .loc_start_exp
.loc_end_exp:
or ecx,ecx
jz .loc_complete
ffree st0 ; <EFBFBD>®ç¨áâ¨âì á⥪
fincstp
mov [digit],10
fild dword [digit]
; „¥«¨âì ¨«¨ 㬭®¦ âì?
mov esi,[exp]
cmp byte [esi],'-'
je .loc_exp_divide
.loc_exp_multiple:
fmul st1,st0
loop .loc_exp_multiple
jmp .loc_complete
.loc_exp_divide:
fdiv st1,st0
loop .loc_exp_divide
.loc_complete:
ffree st0 ; <EFBFBD>®ç¨áâ¨âì á⥪
fincstp
; ­ ç «¥ áâப¨ ¬¨­ãá?
mov esi,[lpStr]
cmp byte [esi],'-'
jne @f
; ˆ§¬¥­¨âì §­ ª ç¨á« 
fchs
@@:
; ‡ ¯¨á âì §­ ç¥­¨¥ ¢ ï祩ªã ¯ ¬ïâ¨
mov eax,[lpResult]
; …᫨ âॡã¥âáï ¯®¢ë襭­ ï â®ç­®áâì, â® ¯à¨¥¬­¨ª
; ¤®«¦¥­ ¨¬¥âì à §¬¥à QWORD,   á«¥¤ãîéãî ª®¬ ­¤ã
; ­ ¤® § ¬¥­¨âì ­  fstp qword [eax]
fstp tword [eax]
; “ᯥ譮¥ ¯à¥®¡à §®¢ ­¨¥
mov [digit],1
.loc_ret:
popa
; <EFBFBD>¥§ã«ìâ â ¯à¥®¡à §®¢ ­¨ï
mov eax,[digit]
ret
endp

View File

@ -0,0 +1,305 @@
;-----------------------------------------------------------------------------+
; ”ã­ªæ¨ï ¯¥à¥¢®¤  ¢¥é¥á⢥­­®£® ç¨á«  ¢ áâபã [ by ManHunter / PCL ] |
;-----------------------------------------------------------------------------|
; <EFBFBD> à ¬¥âàë: |
; lpFloat - 㪠§ â¥«ì ­  ¢¥é¥á⢥­­®¥ ç¨á«® TBYTE |
; lpResult - 㪠§ â¥«ì ­  áâபã-¯à¨¥¬­¨ª १ã«ìâ â  |
;-----------------------------------------------------------------------------+
proc FloatToString lpFloat:DWORD, lpResult:DWORD
; ‹®ª «ì­ë¥ ¯¥à¥¬¥­­ë¥
local digits_count:DWORD
local old_cw:WORD
local new_cw:WORD
local saved_float:TBYTE
local tmp1 rb 11h
local tmp2 rb 11h
; ‘®åà ­¨âì ¢á¥ à¥£¨áâàë
pusha
; “ª § â¥«ì ­  áâபã-¯à¨¥¬­¨ª
mov edi,[lpResult]
; <EFBFBD>â® ­®«ì?
lea esi,[lpFloat]
cmp dword [esi],0
jne loc_not_zero
cmp dword [esi+4],0
jne loc_not_zero
cmp word [esi+8],0
jne loc_not_zero
; ‡ ¯¨á âì ¢ áâப㠭®«ì
mov al,'0'
stosb
jmp loc_ret
loc_not_zero:
; ‘ª®¯¨à®¢ âì ç¨á«® ¢ «®ª «ì­ãî ¯¥à¥¬¥­­ãî
push edi
mov esi,[lpFloat]
lea edi,[saved_float]
movsd
movsd
movsw
pop edi
; —¨á«® ®âà¨æ â¥«ì­®¥?
cmp dword [saved_float+6],0
jge loc_not_signed
; <EFBFBD>ਢ¥á⨠ç¨á«® ª  ¡á®«îâ­®¬ã §­ ç¥­¨î
and byte [saved_float+9],7Fh
; ‡ ¯¨á âì ¢ áâப㠬¨­ãá
mov al,'-'
stosb
loc_not_signed:
; <EFBFBD>஢¥à¨âì ç¨á«® ­  ­ «¨ç¨¥ ¤à®¡­®© ç á⨠¨
; ¯®¤áç¨â âì ª®«¨ç¥á⢮ æ¨äà ¢ ­¥¬
fclex
; ‘®åà ­¨âì ã¯à ¢«ïî饥 á«®¢®
fstcw [old_cw]
; “áâ ­®¢¨âì ã¯à ¢«ïî饥 á«®¢®
mov [new_cw],0000001001111111b
fldcw [new_cw]
lea esi,[saved_float]
fld tbyte [esi]
fld st
; ‚뤥«¨âì ¬ ­â¨ááã ¨ ¯®à冷ª
fxtract
fstp st
fldlg2
; <EFBFBD>®«ãç¨âì ª®«¨ç¥á⢮ æ¨äà ¢ ç¨á«¥
fmulp st1,st
fistp [digits_count]
; …᫨ æ¨äà ¡®«ìè¥ 16, â® ç¨á«® ®â®¡à ¦ ¥âáï ¢
; ­®à¬ «¨§®¢ ­­®¬ ¢¨¤¥ á ¬ ­â¨áᮩ ¨ íªá¯®­¥­â®©
cmp [digits_count],10h
jnb loc_not_integer
; ç¨á«  ¥áâì ¤à®¡­ ï ç áâì?
fld st
frndint
fcomp st1
fstsw ax
test ah,01000000b
; „ , ®â®¡à ¦ âì ç¨á«® á ¤à®¡­®© ç áâìî
jz loc_not_integer
; –¥«®¥ ç¨á«® ¡¥§ ¤à®¡­®© ç á⨠¨ íªá¯®­¥­âë
lea eax,[tmp1]
fbstp [eax]
; <EFBFBD>¥à¥¢¥á⨠BCD-ç¨á«® ¢ áâபã
push edi
lea esi,[tmp1+8]
lea edi,[tmp2]
mov ecx, 9
@@:
std
xor eax,eax
lodsb
cld
rol ax,12
rol ah,4
add ax,'00'
stosw
loop @b
pop edi
; <EFBFBD>யãáâ¨âì «¨¤¨àãî騩 ­®«ì
mov eax,11h
mov ecx,[digits_count]
sub eax,ecx
inc ecx
lea esi,[tmp2+eax]
cmp byte [esi],'0'
jne @f
inc esi
dec ecx
@@:
; <EFBFBD>¥à¥­¥á⨠¯®«ã祭­®¥ ç¨á«® ¨§ ¢à¥¬¥­­®£® ¡ãä¥à 
rep movsb
jmp loc_clear_stack
loc_not_integer:
mov eax,10h
sub eax,[digits_count]
; <EFBFBD>८¡à §®¢ âì ç¨á«® ¢ 楫®¥ ¤® 16 à §à冷¢
mov ecx,eax
cmp eax,0
jge @f
neg eax
@@:
; „«ï ç¨á¥« ¡®«ìè¥ 0 ª®à४â¨à®¢ª  ®ªà㣫¥­¨ï ¢ áâ®à®­ã 0
mov [new_cw],0000101001111111b
cmp ecx,0
jge @f
mov [new_cw],0000011001111111b
@@:
; “áâ ­®¢¨âì ã¯à ¢«ïî饥 á«®¢®
fldcw [new_cw]
; ‚®§¢¥á⨠10 ¢ á⥯¥­ì ª®«¨ç¥á⢠ æ¨äà
fld [float2]
fld [float2]
@@:
fmul st,st1
dec eax
cmp eax,1
ja @b
; <EFBFBD>®ç¨áâ¨âì á⥪
fxch st1
fstp st
; …᫨ ç¨á«® ¬¥­ìè¥ 0, ⮠㬭®¦¨âì, ¨­ ç¥ à §¤¥«¨âì
cmp ecx,0
jge @f
fdivp st1,st
jmp loc_rounded
@@:
fmulp st1,st
loc_rounded:
; <EFBFBD>®«ã祭­®¥ §­ ç¥­¨¥ ¬¥­ìè¥ 1.0e16 ?
fcom [float1]
fstsw ax
test ah,1
jz @f
fmul [float2]
dec [digits_count]
@@:
; –¥«®¥ ç¨á«® ¡¥§ ¤à®¡­®© ç á⨠¨ íªá¯®­¥­âë
lea eax,[tmp1]
fbstp [eax]
; <EFBFBD>¥à¥¢¥á⨠BCD-ç¨á«® ¢ áâபã
push edi
lea esi,[tmp1+8]
lea edi,[tmp2]
mov ecx, 9
@@:
std
xor eax,eax
lodsb
cld
rol ax,12
rol ah,4
add ax,'00'
stosw
loop @b
pop edi
; —¨á«ã âॡã¥âáï ¬ ­â¨áá  ¨ íªá¯®­¥­â ?
lea esi,[tmp2+1]
mov ecx,[digits_count]
cmp ecx,-0Fh
jl loc_mantiss_and_exponent
cmp ecx,10h
jg loc_mantiss_and_exponent
; ‡ ¯®«­¨âì ¤à®¡­ãî ç áâì ç¨á« 
inc ecx
cmp ecx,0
jg @f
mov ax,'0.'
stosw
neg ecx
mov al,'0'
rep stosb
mov ecx,10h
jmp loc_fraction_filled
@@:
rep movsb
mov al,'.'
stosb
mov ecx,10h
sub ecx,[digits_count]
loc_fraction_filled:
rep movsb
jmp @f
loc_clear_fraction:
; “¤ «¨âì § ¢¥àè î騥 ­ã«¨ ¤à®¡­®© ç áâ¨
dec edi
@@:
cmp byte [edi-1],'0'
jz loc_clear_fraction
cmp byte [edi-1],'.'
jnz @f
dec edi
@@:
jmp loc_clear_stack
loc_mantiss_and_exponent:
; „஡­ ï ç áâì ¬ ­â¨ááë
movsb
mov al,'.'
stosb
movsd
movsd
movsw
; “¤ «¨âì § ¢¥àè î騥 ­ã«¨ ¤à®¡­®© ç áâ¨
@@:
cmp byte [edi-1],'0'
jne @f
cmp byte [edi-2],'.'
je @f
dec edi
jmp @b
@@:
; ‘¨¬¢®« ¨ §­ ª íªá¯®­¥­âë
mov al,'e'
stosb
mov al,'+'
mov ebx,[digits_count]
cmp ebx, 0
jge @f
mov al,'-'
neg ebx
@@:
stosb
; ‡­ ç¥­¨¥ íªá¯®­¥­âë
mov eax,ebx
mov ecx,10
mov ebx,4
@@:
dec ebx
xor edx,edx
div ecx
add dl,'0'
mov [tmp1+ebx],dl
or ebx,ebx
jnz @b
; <EFBFBD>யãáâ¨âì «¨¤¨àãî騥 ­ã«¨ íªá¯®­¥­âë
mov ecx,4
lea esi,[tmp1]
@@:
lodsb
cmp al,'0'
jne @f
dec ecx
jmp @b
@@:
dec esi
rep movsb
loc_clear_stack:
; ‚®ááâ ­®¢¨âì ã¯à ¢«ïî饥 á«®¢®
fldcw [old_cw]
loc_ret:
; Žª®­ç ­¨¥ áâப¨
mov al,0
stosb
; ‚®ááâ ­®¢¨âì ¢á¥ à¥£¨áâàë
popa
ret
float1 dq 1.0e16
float2 dq 10.0
endp

View File

@ -0,0 +1,34 @@
;-----------------------------------------------------------------------------+
; ”ã­ªæ¨ï £¥­¥à æ¨¨ á«ãç ©­®£® ç¨á«  ¢ ¤¨ ¯®§®­¥ 0..99999 |
;-----------------------------------------------------------------------------+
; <EFBFBD>  ¢ë室¥ : eax - á«ãç ©­®¥ ç¨á«® |
;-----------------------------------------------------------------------------+
_random:
push edx ecx ebx
mov eax,ebx
or eax,eax
jnz @f
rdtsc
xor eax,edx
mov ebx,eax
@@:
xor edx,edx
mov ecx,127773
div ecx
mov ecx,eax
mov eax,16807
mul edx
mov edx,ecx
mov ecx,eax
mov eax,2836
mul edx
sub ecx,eax
xor edx,edx
mov eax,ecx
mov ebx,ecx
mov ecx,100000
div ecx
mov eax,edx
pop ebx ecx edx
ret
;->

View File

@ -0,0 +1,2 @@
@fasm -m 65536 utils.asm utils.obj
@kpack utils.obj

View File

@ -0,0 +1,88 @@
;-----------------------------------------------------------------------------;
; =[ INIT ]= ;
;-----------------------------------------------------------------------------;
;; START:
call utils_init
;-----------------------------------------------------------------------------;
; =[ USE ]= ;
;-----------------------------------------------------------------------------;
push fvalue ; value dt (XXXXX.XXXXX)
push fstring ; ASCIIZ string (rb 64)
call [_ftoa] ; convert
push fstring ; ASCIIZ string ('XXXX.XXXXXX',0)
push fvalue ; value dt (?)
call [_atof] ; EAX: 0 - error, 1 - convert
call [_random] ; EAX: random digit [0...99999]
;-----------------------------------------------------------------------------;
; =[ LOAD ]= ;
;-----------------------------------------------------------------------------;
utils_init:
mov eax, 68 ; load DLL
mov ebx, 19 ;
mov ecx, utils_lib
int 0x40
test eax, eax
jz utils_exit
mov edx, eax ; initialize import
mov esi, utils_import ; import list
utils_loop:
lodsd
test eax, eax
jz utils_done
push edx
utils_find:
mov ebx, [edx]
test ebx, ebx
jz utils_exit ;import_not_found
push eax
@@:
mov cl, [eax]
cmp cl, [ebx]
jnz utils_next
test cl, cl
jz utils_found
inc eax
inc ebx
jmp @b
utils_next:
pop eax
add edx, 8
jmp utils_find
utils_found:
pop eax
mov eax, [edx+4]
mov [esi-4], eax
pop edx
jmp utils_loop
utils_done:
ret
utils_exit:
mov eax, -1
int 0x40
;-----------------------------------------------------------------------------;
; =[ DATA ]= ;
;-----------------------------------------------------------------------------;
fvalue dt -502556.267e600 ; dt ?
fstring db rb 100 ; '-15.246789',0
utils_lib db '/sys/lib/utils.obj',0 ; path
align 4
utils_import:
_ftoa dd ftoa
_atof dd atof
_random dd random
dd 0
ftoa db 'ftoa',0
atof db 'atof',0
random db 'random',0
;-----------------------------------------------------------------------------;

View File

@ -0,0 +1,64 @@
;-----------------------------------------------------------------------------+
; Library "utils" (c) Sergei Steshin (Akyltist) |
;-----------------------------------------------------------------------------+
; Charset:DOS-866 Font:Courier New Size:9pt |
; compiler: FASM 1.69.31 |
; version: 0.1.0 |
; last update: 31/03/2014 |
; e-mail: dr.steshin@gmail.com |
; license: BSD |
;-----------------------------------------------------------------------------+
format MS COFF
public EXPORTS
section '.flat' code readable writable align 16
include '../../../../proc32.inc'
include '_ftoa.inc'
include '_atof.inc'
include '_rand.inc'
;-----------------------------------------------------------------------------+
; float to ascii string |
;-----------------------------------------------------------------------------+
ftoa: ;
mov ebx, dword [esp+4] ; out string
mov eax, dword [esp+8] ; in value
stdcall FloatToString,eax,ebx ;
ret 8 ;
;-----------------------------------------------------------------------------+
; ascii string to float |
;-----------------------------------------------------------------------------+
atof: ;
mov ebx, dword [esp+4] ; out <- value
mov eax, dword [esp+8] ; in -> string
stdcall string2float,eax,ebx ;
ret 8 ;
;-----------------------------------------------------------------------------+
; returns a random integer in the range [ 0...99999 ] |
;-----------------------------------------------------------------------------+
random: ;
call _random ; out <- eax random
ret ;
;=============================================================================;
align 16
EXPORTS:
dd szFtoa , ftoa
dd szAtof , atof
dd szRandom , random
dd 0 , 0
szFtoa db 'ftoa' ,0
szAtof db 'atof' ,0
szRandom db 'random' ,0
section '.data' data readable writable align 16