flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
dead_body 20 Mar 2007, 22:10
what about writing\reading Float numbers?
and what about 64 bits numbers.... |
|||
![]() |
|
dead_body 21 Mar 2007, 10:25
vid wrote:
i am really need them, and some people too... we will wait... |
|||
![]() |
|
vid 21 Mar 2007, 11:09
sorry, i'm afraid i am not the right one to do it. I am afraid i wouldn't be able to do it properly.
Another solution could be stealing someone's other algorithms |
|||
![]() |
|
LocoDelAssembly 21 Mar 2007, 14:16
Looking at libc source and doing the appropiate port? I think that if you mention that your algo is based on libc you will have no trouble, the license must allow you to do that, isn't it? Otherwise wait for Tomasz
![]() |
|||
![]() |
|
vid 21 Mar 2007, 15:08
i DID look at (g)libc sources. Try looking at them yourself and you will see reason why i didn't choose this way
![]() ![]() |
|||
![]() |
|
dead_body 21 Mar 2007, 18:03
maybe I can write something... I will think about this... maybe...
|
|||
![]() |
|
vid 21 Mar 2007, 18:30
dead_body: i would be glad if you could.
First thing to think about is whether to use FPU or not. if you use FPU you get rounding problems. Doing it just with normal instruction is bigger problem ![]() if you would be interested, please let me know. You would need to adhere few rules, so it can be used (mostly, support few formats needed) |
|||
![]() |
|
dead_body 22 Mar 2007, 07:32
vid wrote: if you would be interested, please let me know. You would need to adhere few rules, so it can be used (mostly, support few formats needed) what rules? i have an interest... |
|||
![]() |
|
vid 22 Mar 2007, 10:41
as first, you could try to do conversion from ASCII format to floating point. Conversion to ascii is harder, as we must support more options, and i must think about it a little bit more.
Here are rules for "extconv.fp2t string, buflen" - converts ascii string to tbyte floating point number - accepts forms "-10", "4.51332533", "+3.4", "1e20", "-5.3e-20", "4e+30" - number of digits is not limited, so even thousand zeroes followed by real number should be converted just like the zeroes weren't there. same applies to exponent. - takes 2 arguments: pointer to ascii string and length of string buffer - function cannot access memory behind end of buffer. - if first char isn't valid FP number character, function returns CF=1, and EAX=ERR_NOT_FLOAT - any unexpected (non-float) character can terminate conversion. For eample in "10d", only "10" is converted. - if number is not completed ("10.", "10.z", "1.5e-"), function returns ERR_BAD_FLOAT - if number doesn't fit into register, function returns ERR_OUT_OF_RANGE that is all that comes to my mind. if there are any problems just ask Last edited by vid on 24 Mar 2007, 12:09; edited 1 time in total |
|||
![]() |
|
dead_body 24 Mar 2007, 11:48
what it must return?
result in ST0? or maybe it will recieve a pointer to var(tbyte) and there we will store our number?(and here BCD or extended float) |
|||
![]() |
|
vid 24 Mar 2007, 11:55
in case of error CF=1, EAX=error code (ERR_SOMETHING constant)
in case of no error CF=0, ST0=converted number. All other general purpose registers should be preserved. i think ST0 is better than pointer to variable, often you want to use number just after converting. If no, it's easy to store the return value. another problem to consider is yout STx registers usage. After return, value must be pushed on stack, and all things that were there before should remain. So when before calling there was: ST0=0.0 ST1=-5.0e3 after return it should be ST0=return value ST1=0.0 ST2=-5.0e3 It would be best if you could preserve all 6 ST registers somehow. If not, at least mention in documentation how many ST registers are used internally by function. |
|||
![]() |
|
Vasilev Vjacheslav 24 Mar 2007, 12:23
try to port FPULIB from masm package
|
|||
![]() |
|
ATV 26 Mar 2007, 12:18
Vid, here is two routines to start with. (without error checking)
Code: ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; ascii2float (buffer, number) ; param: buffer -> Asciiz string ; number -> pointer for qword number ; notes: number range is 1e-300 to 1e300 ; all number before and after dot '.' are added with st=st*10+new_number ; when numbers end divide by 10 with count of numbers after dot ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- proc ascii2float \ buffer:DWORD,\ number:DWORD push eax ebx ecx edx esi mov esi,[buffer] fninit fldz or ecx,-1 ; digit count after '.' (-1 = none) xor ebx,ebx ; ebx: bit0 = mantissa sign , bit1 = exp sign xor edx,edx ; exponent .test_sign: cmp byte [esi],'+' je .sign_skip cmp byte [esi],'-' jne .new_char xor ebx,1 .sign_skip: inc esi jmp .test_sign .new_char: movzx eax,byte [esi] cmp al,'.' je .separator cmp al,',' jne .not_separator .separator: xor ecx,ecx jmp .next_number .not_separator: cmp al,'e' je .exponent cmp al,'E' je .exponent sub al,'0' cmp al,9 ja .number_end push eax fmul [f10] fiadd dword [esp] pop eax or ecx,ecx js .next_number inc ecx .next_number: inc esi jmp .new_char .exponent: inc esi cmp byte [esi],'+' je .exponent cmp byte [esi],'-' jne .exp_char xor ebx,2 jmp .exponent .exp_char: movzx eax,byte [esi] sub al,'0' cmp al,9 ja .number_end imul edx,10 add edx,eax inc esi cmp edx,30 jb .exp_char .number_end: cmp ecx,1 jl .add_exp fdiv [f10] dec ecx jmp .number_end .add_exp: test edx,edx jz .exp_ok dec edx test ebx,2 jz .exp_positive fdiv [f10] jmp .add_exp .exp_positive: fmul [f10] jmp .add_exp .exp_ok: test ebx,1 jz .sign_ok fchs .sign_ok: mov ebx,[number] fstp qword [ebx] pop esi edx ecx ebx eax ret endp Code: ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; float2ascii (number, count, buffer) ; put float value ?.? into buffer ; param: number -> pointer to qword number ; count -> count of digits to display after dot '.' ; buffer -> buffer for Asciiz string ; notes: number range is 1e-300 to 1e300 ; if number is below 1e-15 or above 1e15 use exponent format ; ToDo: better rounding (display 1.2 not 1.199999...) ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- proc float2ascii \ number:DWORD,\ count:DWORD,\ buffer:DWORD local old_cw:WORD,\ new_cw:WORD,\ packed_BCD:TBYTE,\ BCD_buffer[20]:BYTE push eax ebx ecx edx esi edi mov edi,[buffer] xor edx,edx ; exponent fninit fstcw [old_cw] mov ax,[old_cw] or ax,0000110000000000b ; no fpu rounding mov [new_cw],ax fldcw [new_cw] mov ebx,[number] fld qword [ebx] ftst fstsw ax sahf jp .error je .mantissa jnc .positive fabs mov byte [edi],'-' inc edi .positive: fcom [f1e_300] ; test if too small fstsw ax sahf jb .mantissa fcom [f1e_15] ; test if too many zeros fstsw ax sahf jb .test1 fcom [f1e15] ; test if too many digits fstsw ax sahf jb .mantissa .test10: fcom [f10] fstsw ax sahf jb .mantissa inc edx fdiv [f10] jmp .test10 .test1: fcom [f1] fstsw ax sahf jnb .mantissa dec edx fmul [f10] jmp .test1 .error: mov dword [edi],'ERRO' mov word [edi+4],'R' add edi,5 jmp .float_end .mantissa: lea ebx,[packed_BCD] fld st fbstp [ebx] lea esi,[BCD_buffer] mov ecx,9 ; 9 packed BCD numbers + sign byte .unpack_BCD: movzx eax,byte [ebx] inc ebx shl eax,4 shr al,4 mov [esi],ax add esi,2 loop .unpack_BCD lea ecx,[BCD_buffer] ; start of BCD buffer .skip_zero: dec esi cmp byte [esi],0 jne .number cmp esi,ecx ; don't skip last 0 ja .skip_zero .number: mov al,[esi] ; convert byte -> ASCII dec esi or al,'0' mov [edi],al inc edi cmp esi,ecx jae .number mov ecx,[count] ; digit count after dot or cl,cl je .float_end cmp cl,15 ; if over 15 it must be error jb .dot mov cl,8 ; use default 8 digits .dot: mov byte [edi],'.' inc edi .new_decimal: fld st ; digit = (st-int(st))*10 frndint fsubp ; use only decimal part fmul [f10] ; get first digit after dot fist dword [edi] ; and save it or byte [edi],'0' inc edi dec cl ; loop until all decimals are done jnz .new_decimal round_result = 0 if round_result = 1 fmul [f10] fist dword [edi] cmp byte [edi],5 jb .round_ok mov ebx,edi .round_more: dec ebx mov al,[ebx] cmp al,'0' jb .round_ok cmp al,'9' ja .round_ok jb .do_inc mov byte [ebx],'0' jmp .round_more .do_inc: inc byte [ebx] .round_ok: end if .exp_sign: mov al,'+' or edx,edx jz .float_end jns .exp_positive neg edx mov al,'-' .exp_positive: mov byte [edi],'e' ; put exponent: 'e+000' inc edi mov [edi],al inc edi mov eax,edx mov ebx,10 mov ecx,2 .exp_loop: xor edx,edx div ebx or dl,'0' mov [edi+ecx],dl dec ecx jns .exp_loop add edi,3 .float_end: fldcw [old_cw] mov byte [edi],0 pop edi esi edx ecx ebx eax ret endp ; data f1 dq 1.0 f10 dq 10.0 f1e_300 dq 1e-300 f1e15 dq 1e15 f1e_15 dq 1e-15 |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.