flat assembler
Message board for the users of flat assembler.

Index > Windows > Convert Floating Point Number To String

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
hi...
i want to complete this code:
Code:
; example of simplified Windows programming using complex macro features

include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here

.code

  start:

        invoke  MessageBox,HWND_DESKTOP,float1,invoke GetCommandLine,MB_OK ; i want to print string(float1)...
        fld [float1]     ; Push float1 value to ST(0)
        fadd [float2]    ; Add float2 to ST(0)
        fstp [float1]    ; Pop value from ST(0) to float1
        invoke  MessageBox,HWND_DESKTOP,str1,invoke GetCommandLine,MB_OK ; i want to print string(float1)...
        invoke  ExitProcess,0

.end start

.data

float1 dq 123.12
float2 dq 34.45

str1 db 'converted float here...',0
    

to convert a floating point number to string and show it...
is there any easy to use macro, procedure or something?
sorry if this is FAQ... Wink
Post 14 Sep 2012, 16:20
View user's profile Send private message Yahoo Messenger Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
There was some conversion routines posted here -- search the forum.
If you wish to have some fun converting it -- read about the FBSTP instruction.
Post 14 Sep 2012, 18:21
View user's profile Send private message Send e-mail Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
thanks for answer...
i found this before: http://board.flatassembler.net/topic.php?t=4377&start=53
but i had problem with including extra.inc, finally my problem solved with Vasilev Vjacheslav's post in there...
i love you fasm!
Post 14 Sep 2012, 19:30
View user's profile Send private message Yahoo Messenger Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
hi...
i have another question...
for example in this program:
Code:
 format pe gui 4.0
entry start

include '..\include\win32ax.inc'

BUFF_SIZE   = 256

section '.rdata' data readable writeable

  figure1        dq 0.003
  figure2   dq -0.003
  figure3  dq 1234.567
  figure4        dq -1234.567
  figure5       dq 123456.789
  figure6      dq -123456.789

  zero            dq 0.0
  z1          dq 0.01
  z3         dq 0.03
  d1         dq 0.1
  one         dq 1.0
  ten         dq 10.0
  mten               dq -10.0
  nine              dq 9999.9

  szMinus      db "-",0
  szNullDot       db "0.",0
  szNull db "0",0
  szDot   db ".",0
  szExp   db "E",0

  digits      db "0123456789ABCDEF",0

section '.data' readable writeable

  szBuffer rb BUFF_SIZE

section '.text' code readable writable executable

  ; -------------------------------------------------
  ;
  ; entry-point
  ;
  ; -------------------------------------------------

  start:

      fld [figure1]         ; Push float1 value to ST(0)
  ;fadd [figure3]    ; Add float2 to ST(0)
    fsqrt
       fstp [figure1]    ; Pop value from ST(0) to float1

      stdcall _ftoa,double [figure1],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      stdcall _ftoa,double [figure2],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      stdcall _ftoa,double [figure3],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      stdcall _ftoa,double [figure4],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      stdcall _ftoa,double [figure5],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      stdcall _ftoa,double [figure6],szBuffer
     invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

      invoke  ExitProcess,NULL

  ; -------------------------------------------------
  ;
  ; convert double or float to ascii with proper
  ; rounding and formatting
  ;
  ; -------------------------------------------------

  proc   _ftoa uses ebx esi edi,hx:QWORD,hstr
  locals
        hdecm   dd ?
  endl

  mov     esi,[hstr]
  xor     ebx,ebx
     xor     edi,edi
     cmp     esi,ebx
     mov     [hdecm],ebx
 je      .out
        fld     [zero]
      fld     [hx]
        fucompp
     fnstsw  ax
  test    ah,68
       jp      @F
  invoke  lstrcpy,esi,szNull
  jmp     .out
  @@:
   fld     [hx]
        fcomp   [zero]
      fnstsw  ax
  test    ah,5
        jp      @F
  mov     ebx,1
       fld     [hx]
        fchs
        fstp    [hx]
  @@:
   fld     [hx]
        fcomp   [z1]
        fld     [hx]
        fnstsw  ax
  test    ah,5
        jp      .a
  fcomp   [d1]
        fnstsw  ax
  test    ah,5
        jp      .conv
  @@:
  fld     [hx]
        dec     edi
 fmul    [ten]
       fstp    [hx]
        fld     [hx]
        fcomp   [d1]
        fnstsw  ax
  test    ah,5
        jnp     @B
  jmp     .conv
  .a:
  fcomp   [nine]
      fnstsw  ax
  test    ah,65
       jne     .conv
       fld     [hx]
        fcomp   [ten]
       fnstsw  ax
  test    ah,1
        jne     .conv
  @@:
  fld     [hx]
        inc     edi
 fdiv    [ten]
       fstp    [hx]
        fld     [hx]
        fcomp   [ten]
       fnstsw  ax
  test    ah,1
        je      @B
  .conv:
  lea     edx,[hdecm]
 stdcall _cvt,double [hx],3,edx,esi
  mov     eax,[hdecm]
 stdcall _formatstring,esi,eax,ebx,edi
  .out:
        ret
  endp

  ; -------------------------------------------------
  ;
  ; format ascii figure according to decimal place
  ; and exponent
  ;
  ; -------------------------------------------------

  proc       _formatstring uses ebx esi edi,hstr,hdec,hsign,hexp
  locals
     buf1    rb 64
       buf2    rb 64
  endl

 xor     eax,eax
     mov     [buf1],al
   mov     [buf2],al
   mov     eax,[hsign]
 test    eax,eax
     je      @F
  lea     eax,[buf1]
  invoke  lstrcat,eax,szMinus

  @@:
        mov     esi,[hdec]
  test    esi,esi
     jg      .b
  lea     ecx,[buf1]
  invoke  lstrcat,ecx,szNullDot
       test    esi,esi
     jge     .a
  neg     esi
  @@:
    lea     edx,[buf1]
  invoke  lstrcat,edx,szNull
  dec     esi
 jne     @B
  .a:
     mov     ebx,[hstr]
  lea     eax,[buf1]
  invoke  lstrcat,eax,ebx
     jmp     .d
  .b:
     mov     ebx,[hstr]
  stdcall _strlen_fog,ebx
     lea     ecx,[buf1]
  mov     edi,eax
     stdcall _strncat,ecx,ebx,esi
        cmp     edi,esi
     je      .d
  lea     edx,[buf1]
  invoke  lstrcat,edx,szDot
   lea     eax,[ebx+esi]
       lea     ecx,[buf1]
  invoke  lstrcat,ecx,eax
  .d:
        lea     edx,[buf1]
  stdcall _strlen_fog,edx
     dec     eax
 je      .c
  @@:
     cmp     byte [buf1+eax],'0'
       jne     .c
  dec     eax
 mov     byte [buf1+eax+1],0
 jne     @B

  .c:
 mov     cl,byte [buf1+eax]
  cmp     cl,'.'
    lea     eax,[buf1+eax]
      jne     @F
  mov     byte [eax],0
  @@:
   mov     eax,[hexp]
  test    eax,eax
     je      @F
  lea     ecx,[buf2]
  stdcall _itoa,eax,ecx
       lea     edx,[buf1]
  invoke  lstrcat,edx,szExp
   lea     eax,[buf2]
  lea     ecx,[buf1]
  invoke  lstrcat,ecx,eax
  @@:
        lea     edx,[buf1]
  invoke  lstrcpy,ebx,edx
  .out:
      ret
  endp

  ; -------------------------------------------------
  ;
  ; convert double/float to a string with proper
  ; rounding
  ;
  ; -------------------------------------------------

  proc     _cvt uses ebx esi edi, harg:QWORD,hdigits,hdecpt,hbuf
  locals
       r2      dd ?
        fi      dq ?
        fj      dq ?
        tmp     dq ?
  endl

  mov     eax,[hdigits]
       xor     esi,esi
     cmp     eax,esi
     jge     @F
  mov     [hdigits],esi
       jmp     .a
  @@:
     cmp     eax,BUFF_SIZE-1
     jl      .a
  mov     [hdigits],BUFF_SIZE-2
  .a:
  mov     ebx,[hbuf]
  mov     [r2],esi
    mov     edi,ebx
     fld     [harg]
      fcomp   [zero]
      fnstsw  ax
  test    ah,5
        jp      @F
  fld     [harg]
      fchs
        fstp    [harg]
  @@:
 lea     eax,[fi]
    stdcall _modf,double [harg],eax
     fstp    [harg]
      fld     [zero]
      fld     [fi]
        fucompp
     fnstsw  ax
  test    ah,68
       jnp     .int_is_zero
        lea     esi,[ebx+BUFF_SIZE]
  @@:
    fld     [fi]
        fdiv    [ten]
       fstp    [tmp]
       lea     ecx,[fi]
    stdcall _modf,double [tmp],ecx
      fadd    [z3]
        fmul    [mten]
      fistp   [tmp]
       dec     esi
 mov     dl,byte [tmp]
       mov     al,'0'
    sub     al,dl
       mov     [esi],al
    mov     eax,[r2]
    inc     eax
 mov     [r2],eax
    fld     [zero]
      fld     [fi]
        fucompp
     fnstsw  ax
  test    ah,68
       jp      @b
  lea     eax,[ebx+BUFF_SIZE]
 cmp     esi,eax
     jae     .b
  @@:
     mov     cl,[esi]
    mov     [edi],cl
    inc     edi
 inc     esi
 cmp     esi,eax
     jb      @B
  .b:
     mov     esi,[r2]
  .j:
       mov     edx,[hdigits]
       mov     eax,[r2]
    mov     ecx,[hdecpt]
        add     esi,edx
     add     esi,ebx
     cmp     esi,ebx
     mov     [ecx],eax
   jae     .h
  mov     byte [ebx],0
        jmp     .out

  .int_is_zero:
     fld     [harg]
      fcomp   [zero]
      fnstsw  ax
  test    ah,65
       jnz     .j
  fld     [harg]
      fmul    [ten]
       fstp    [fj]
        fld     [fj]
        fcomp   [one]
       fnstsw  ax
  test    ah,5
        jp      .j
  @@:
     dec     esi
 fld     [fj]
        fstp    [harg]
      fld     [fj]
        fmul    [ten]
       fstp    [fj]
        fld     [fj]
        fcomp   [one]
       fnstsw  ax
  test    ah,5
        jnp     @B
  mov     [r2],esi
    jmp     .j
  .h:
     cmp     edi,esi
     ja      .c
  @@:
     lea     eax,[ebx+BUFF_SIZE]
 cmp     edi,eax
     jae     .c
  lea     ecx,[fj]
    fld     [harg]
      fmul    [ten]
       fstp    [harg]
      stdcall _modf,double [harg],ecx
     mov     ecx,[hdecpt]
        fstp    [harg]
      fld     [fj]
        fistp   [tmp]
       mov     dl,byte [tmp]
       add     dl,'0'
    mov     [edi],dl
    inc     edi
 cmp     edi,esi
     jbe     @B
  .c:
     lea     eax,[ebx+BUFF_SIZE]
 cmp     esi,eax
     jb      @F
  mov     byte [ebx+255],0
    jmp     .out

  @@:
       mov     dl,[esi]
    add     dl,5
        mov     eax,esi
     mov     [esi],dl
    cmp     dl,'9'
    jle     .d
  .g:
     mov     byte [esi],'0'
    cmp     esi,ebx
     jbe     .e
  mov     dl,[esi-1]
  dec     esi
 inc     dl
  mov     [esi],dl
    jmp     .f
  .e:
     mov     byte [esi],'1'
    mov     edi,[ecx]
   inc     edi
 cmp     eax,ebx
     mov     [ecx],edi
   jbe     @F
  mov     byte [eax],'0'
  @@:
       inc     eax
  .f:
    cmp     byte [esi],'9'
    jg      .g
  .d:
     mov     byte [eax],0
  .out:
 mov     eax,ebx
     ret
  endp

  ; -------------------------------------------------
  ;
  ; return fractional part in st0 and integer
  ; part in y (pointer to a qword)
  ;
  ; -------------------------------------------------

  proc  _modf uses edi, x:QWORD,y
  locals
   cw1     dw ?
        cw2     dw ?
  endl
      mov     edi,[y]
     fnstcw  [cw1]
       fwait
       mov     ax,[cw1]
    or      ax,110000111111b
    mov     [cw2],ax
    fldcw   [cw2]
       fwait
       fld     [x]
 frndint
     fstp    qword [edi]
 fwait
       fld     [x]
 fsub    qword [edi]
 fldcw   [cw1]
       fwait
       ret
  endp

  ; -------------------------------------------------
  ;
  ; integer to ascii conversion (reverend)
  ;
  ; -------------------------------------------------

  proc   _itoa uses ebx esi edi, number,result_buffer
  locals
    temp_buffer                   rb 32+1
  endl

 push    10
  pop     esi
 lea     edi,[temp_buffer+32]
        mov     ebx,digits
  cmp     esi,16
      ja      .error
      std
 xor     al,al
       stosb
       mov     eax,[number]
        test    eax,80000000h
       jz      @F
  neg     eax
  @@:
    xor     edx,edx
     idiv    esi
 xchg    eax,edx
     xlatb
       stosb
       xchg    eax,edx
     test    eax,eax
     jnz     @B
  lea     esi,[edi+1]
 mov     edi,[result_buffer]
 cld
 test    [number],80000000h
  jz      @F
  mov     al,'-'
    stosb
  @@:
  lodsb
       stosb
       test    al,al
       jnz     @B
  sub     edi,[result_buffer]
 lea     eax,[edi-1]
 stc
 jmp     .theend
  .error:
    clc
  .theend:
       cld
 ret
  endp

  ; -------------------------------------------------
  ;
  ; return length of hstr string in eax (Agner Fog)
  ; pretty fast algorithm
  ;
  ; -------------------------------------------------

  proc     _strncat uses ebx esi edi, hfront,hback,hcount
      mov     esi,[hfront]
        stdcall _strlen_fog,esi
     mov     edx,eax
     add     edx,esi
     mov     edi,[hcount]
        test    edi,edi
     jz      .out_null
   mov     esi,[hback]
  @@:
    mov     cl,[esi]
    mov     [edx],cl
    dec     edi
 inc     edx
 inc     esi
 test    cl,cl
       jz      .out
        test    edi,edi
     jnz     @B
  .out_null:
      xor     al,al
       mov     byte [edx],al
  .out:
        ret
  endp

  ; -------------------------------------------------
  ;
  ; return length of hstr string in eax (Agner Fog)
  ; pretty fast algorithm
  ;
  ; -------------------------------------------------

  proc     _strlen_fog uses ebx esi edi, hstr
  mov     eax,[hstr]
  lea     edx,[eax+3]
  @@:
    mov     ebx,[eax]
   add     eax,4
       lea     ecx,[ebx-01010101h]
 not     ebx
 and     ecx,ebx
     and     ecx,80808080h
       jz      @B
  test    ecx,00008080h
       jnz     @F
  shr     ecx,16
      add     eax,2
  @@:
  shl     cl,1
        sbb     eax,edx
     ret
  endp

  ; -------------------------------------------------
  ;
  ; fast memory copying algorithm (tuned asmpack ver)
  ; qword -> dword -> byte
  ;
  ; -------------------------------------------------

  proc    _memcpy_fast uses esi edi, hdst,hsrc,hsize
  mov     eax,[hsize]
 mov     edi,[hdst]
  mov     esi,[hsrc]
  mov     ecx,eax
     shr     ecx,3
       jz      .next1
  @@:
 movq    mm0,qword [esi]
     movq    qword [edi],mm0
     add     esi,8
       add     edi,8
       dec     ecx
 jnz     @B
  .next1:
 mov     ecx,eax
     and     ecx,7
       shr     ecx,2
       jz      .next2
  @@:
 mov     edx,[esi]
   mov     [edi],edx
   add     esi,4
       add     edi,4
       dec     ecx
 jnz     @B
  .next2:
 and     eax,3
       jz      .out
  @@:
   mov     dl,byte [esi]
       mov     byte [edi],dl
       inc     esi
 inc     edi
 dec     eax
 jnz     @B
  .out:
   sub     edi,[hsize]
 mov     eax,edi
     ret
  endp

section '.idata' import data readable writeable

  library kernel32,'kernel32.dll',\
                user32,'user32.dll',\
            gdi32,'gdi32.dll',\
              comdlg32,'comdlg32.dll',\
                advapi32,'advapi32.dll'

  include      '..\include\api\kernel32.inc'
  include '..\include\api\user32.inc'
  include   '..\include\api\gdi32.inc'
  include    '..\include\api\comdlg32.inc'
  include '..\include\api\advapi32.inc'

; eof    

we used dq for defining floating point numbers. but i don't know actually what type of floating point number they are. half? single? double? ...? how we can implement these types?
Post 14 Sep 2012, 21:58
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17279
Location: In your JS exploiting you and your system
revolution
dq is 64-bit, this corresponds to C type double.
Post 14 Sep 2012, 23:39
View user's profile Send private message Visit poster's website Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
thanks!
so how we can work with other types of floating point numbers? for example 32-bit float...
Post 15 Sep 2012, 00:16
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17279
Location: In your JS exploiting you and your system
revolution
Code:
dd 3.14159 ;32-bit float    
Post 15 Sep 2012, 00:33
View user's profile Send private message Visit poster's website Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
i don't know too much about IEEE 754, but i'm wondering how FPU knows that we have dd or dq?!
Post 15 Sep 2012, 00:45
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17279
Location: In your JS exploiting you and your system
revolution
You specify the type with the instruction encoding.
Code:
fld dword[pointer] ;32-bit load
fld qword[pointer] ;64-bit load    
Post 15 Sep 2012, 00:49
View user's profile Send private message Visit poster's website Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
sorry i'm beginner... Wink could you explain what i have to do after changing dq to dd in that example? i think only that change is not enough...
thank you so much for your help!
Post 15 Sep 2012, 01:34
View user's profile Send private message Yahoo Messenger Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
In case of 32 bit float values you do not have to declare them,
you can simply push them and use them from stack.
Stack, of course, needs to be cleaned before return from a function.
Code:
     Var1    DQ      104.956868
  ...

     ;
   ; ST0 = PI/2 + Var1*1.8373
  ;
   fldpi
       push    2
   fidiv   dword [esp]     ; Integer division from stack!
      fld     [Var1]
      push    1.8373
      fmul    dword [esp]
 faddp
       sub     esp, 2*4        ; Restore stack (or else!)
    

I think 64-bit constants also can be put on stack - I just never used them in my code.
Post 15 Sep 2012, 12:23
View user's profile Send private message Send e-mail Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
If you change the declaration from DQ to DD, you do not need need to change the code.
If you do not specify the type override (dword or qword) FASM will use the type
with which the variable is declared: DD or DQ.
If you load the data into FPU from a pointer, then you need that type (dword or qword).
But you need to be sure that data at the pointer is the assumed type.

OR you can write a small macro:
Code:
    macro L64Fpu r32
    {
              fld     qword [r32]
 }

  ...

     L64Fpu  esi
 L64Fpu  edi
    
Post 15 Sep 2012, 12:25
View user's profile Send private message Send e-mail Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
thanks for replies.
i just changed DQs to DD:
Code:
section '.rdata' data readable writeable

  figure1       dd 3.3
  figure2       dd -0.003

  zero          dd 0.0
  z1            dd 0.01
  z3            dd 0.03
  d1            dd 0.1
  one           dd 1.0
  ten           dd 10.0
  mten          dd -10.0
  nine          dd 9999.9

  szMinus       db "-",0
  szNullDot     db "0.",0
  szNull        db "0",0
  szDot         db ".",0
  szExp         db "E",0

  digits        db "0123456789ABCDEF",0         
    

but _ftoa procedure does not work properly... that procedure is written for dq... i think i have to change that, but i can't understand _ftoa...
Post 15 Sep 2012, 13:21
View user's profile Send private message Yahoo Messenger Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
Did you import _ftoa from some library?
Post 16 Sep 2012, 10:59
View user's profile Send private message Send e-mail Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
no, that is just a part of fourth post code in this topic...
Post 16 Sep 2012, 14:01
View user's profile Send private message Yahoo Messenger Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
I think the FTOA procedure you mentioned is for converting ST0 into a text.
So, I am not sure what you mean by "written for DQ".
Can you post the code how you call FTOA?
Post 16 Sep 2012, 17:27
View user's profile Send private message Send e-mail Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
Code:
 format pe gui 4.0
entry start

include '..\include\win32ax.inc'

BUFF_SIZE       = 256

section '.rdata' data readable writeable

  figure1       dd 0.0030000
  figure2       dd -0.003
  figure3       dd 1234.567
  figure4       dd -1234.567
  figure5       dd 123456.789
  figure6       dd -123456.789

  zero          dd 0.0
  z1            dd 0.01
  z3            dd 0.03
  d1            dd 0.1
  one           dd 1.0
  ten           dd 10.0
  mten          dd -10.0
  nine          dd 9999.9

  szMinus       db "-",0
  szNullDot     db "0.",0
  szNull        db "0",0
  szDot         db ".",0
  szExp         db "E",0

  digits        db "0123456789ABCDEF",0

section '.data' readable writeable

  szBuffer      rb BUFF_SIZE

section '.text' code readable writable executable

  ; -------------------------------------------------
  ;
  ; entry-point
  ;
  ; -------------------------------------------------

  start:

        fld [figure1]         ; Push float1 value to ST(0)
        ;fadd [figure3]    ; Add float2 to ST(0)
        fsqrt
        fstp [figure1]    ; Pop value from ST(0) to float1

        stdcall _ftoa,double [figure1],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        stdcall _ftoa,double [figure2],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        stdcall _ftoa,double [figure3],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        stdcall _ftoa,double [figure4],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        stdcall _ftoa,double [figure5],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        stdcall _ftoa,double [figure6],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        invoke  ExitProcess,NULL

  ; -------------------------------------------------
  ;
  ; convert double or float to ascii with proper
  ; rounding and formatting
  ;
  ; -------------------------------------------------

  proc  _ftoa uses ebx esi edi,hx:QWORD,hstr
  locals
        hdecm   dd ?
  endl

        mov     esi,[hstr]
        xor     ebx,ebx
        xor     edi,edi
        cmp     esi,ebx
        mov     [hdecm],ebx
        je      .out
        fld     [zero]
        fld     [hx]
        fucompp
        fnstsw  ax
        test    ah,68
        jp      @F
        invoke  lstrcpy,esi,szNull
        jmp     .out
  @@:
        fld     [hx]
        fcomp   [zero]
        fnstsw  ax
        test    ah,5
        jp      @F
        mov     ebx,1
        fld     [hx]
        fchs
        fstp    [hx]
  @@:
        fld     [hx]
        fcomp   [z1]
        fld     [hx]
        fnstsw  ax
        test    ah,5
        jp      .a
        fcomp   [d1]
        fnstsw  ax
        test    ah,5
        jp      .conv
  @@:
        fld     [hx]
        dec     edi
        fmul    [ten]
        fstp    [hx]
        fld     [hx]
        fcomp   [d1]
        fnstsw  ax
        test    ah,5
        jnp     @B
        jmp     .conv
  .a:
        fcomp   [nine]
        fnstsw  ax
        test    ah,65
        jne     .conv
        fld     [hx]
        fcomp   [ten]
        fnstsw  ax
        test    ah,1
        jne     .conv
  @@:
        fld     [hx]
        inc     edi
        fdiv    [ten]
        fstp    [hx]
        fld     [hx]
        fcomp   [ten]
        fnstsw  ax
        test    ah,1
        je      @B
  .conv:
        lea     edx,[hdecm]
        stdcall _cvt,double [hx],3,edx,esi
        mov     eax,[hdecm]
        stdcall _formatstring,esi,eax,ebx,edi
  .out:
        ret
  endp

  ; -------------------------------------------------
  ;
  ; format ascii figure according to decimal place
  ; and exponent
  ;
  ; -------------------------------------------------

  proc  _formatstring uses ebx esi edi,hstr,hdec,hsign,hexp
  locals
        buf1    rb 64
        buf2    rb 64
  endl

        xor     eax,eax
        mov     [buf1],al
        mov     [buf2],al
        mov     eax,[hsign]
        test    eax,eax
        je      @F
        lea     eax,[buf1]
        invoke  lstrcat,eax,szMinus

  @@:
        mov     esi,[hdec]
        test    esi,esi
        jg      .b
        lea     ecx,[buf1]
        invoke  lstrcat,ecx,szNullDot
        test    esi,esi
        jge     .a
        neg     esi
  @@:
        lea     edx,[buf1]
        invoke  lstrcat,edx,szNull
        dec     esi
        jne     @B
  .a:
        mov     ebx,[hstr]
        lea     eax,[buf1]
        invoke  lstrcat,eax,ebx
        jmp     .d
  .b:
        mov     ebx,[hstr]
        stdcall _strlen_fog,ebx
        lea     ecx,[buf1]
        mov     edi,eax
        stdcall _strncat,ecx,ebx,esi
        cmp     edi,esi
        je      .d
        lea     edx,[buf1]
        invoke  lstrcat,edx,szDot
        lea     eax,[ebx+esi]
        lea     ecx,[buf1]
        invoke  lstrcat,ecx,eax
  .d:
        lea     edx,[buf1]
        stdcall _strlen_fog,edx
        dec     eax
        je      .c
  @@:
        cmp     byte [buf1+eax],'0'
        jne     .c
        dec     eax
        mov     byte [buf1+eax+1],0
        jne     @B

  .c:
        mov     cl,byte [buf1+eax]
        cmp     cl,'.'
        lea     eax,[buf1+eax]
        jne     @F
        mov     byte [eax],0
  @@:
        mov     eax,[hexp]
        test    eax,eax
        je      @F
        lea     ecx,[buf2]
        stdcall _itoa,eax,ecx
        lea     edx,[buf1]
        invoke  lstrcat,edx,szExp
        lea     eax,[buf2]
        lea     ecx,[buf1]
        invoke  lstrcat,ecx,eax
  @@:
        lea     edx,[buf1]
        invoke  lstrcpy,ebx,edx
  .out:
        ret
  endp

  ; -------------------------------------------------
  ;
  ; convert double/float to a string with proper
  ; rounding
  ;
  ; -------------------------------------------------

  proc  _cvt uses ebx esi edi, harg:QWORD,hdigits,hdecpt,hbuf
  locals
        r2      dd ?
        fi      dq ?
        fj      dq ?
        tmp     dq ?
  endl

        mov     eax,[hdigits]
        xor     esi,esi
        cmp     eax,esi
        jge     @F
        mov     [hdigits],esi
        jmp     .a
  @@:
        cmp     eax,BUFF_SIZE-1
        jl      .a
        mov     [hdigits],BUFF_SIZE-2
  .a:
        mov     ebx,[hbuf]
        mov     [r2],esi
        mov     edi,ebx
        fld     [harg]
        fcomp   [zero]
        fnstsw  ax
        test    ah,5
        jp      @F
        fld     [harg]
        fchs
        fstp    [harg]
  @@:
        lea     eax,[fi]
        stdcall _modf,double [harg],eax
        fstp    [harg]
        fld     [zero]
        fld     [fi]
        fucompp
        fnstsw  ax
        test    ah,68
        jnp     .int_is_zero
        lea     esi,[ebx+BUFF_SIZE]
  @@:
        fld     [fi]
        fdiv    [ten]
        fstp    [tmp]
        lea     ecx,[fi]
        stdcall _modf,double [tmp],ecx
        fadd    [z3]
        fmul    [mten]
        fistp   [tmp]
        dec     esi
        mov     dl,byte [tmp]
        mov     al,'0'
        sub     al,dl
        mov     [esi],al
        mov     eax,[r2]
        inc     eax
        mov     [r2],eax
        fld     [zero]
        fld     [fi]
        fucompp
        fnstsw  ax
        test    ah,68
        jp      @b
        lea     eax,[ebx+BUFF_SIZE]
        cmp     esi,eax
        jae     .b
  @@:
        mov     cl,[esi]
        mov     [edi],cl
        inc     edi
        inc     esi
        cmp     esi,eax
        jb      @B
  .b:
        mov     esi,[r2]
  .j:
        mov     edx,[hdigits]
        mov     eax,[r2]
        mov     ecx,[hdecpt]
        add     esi,edx
        add     esi,ebx
        cmp     esi,ebx
        mov     [ecx],eax
        jae     .h
        mov     byte [ebx],0
        jmp     .out

  .int_is_zero:
        fld     [harg]
        fcomp   [zero]
        fnstsw  ax
        test    ah,65
        jnz     .j
        fld     [harg]
        fmul    [ten]
        fstp    [fj]
        fld     [fj]
        fcomp   [one]
        fnstsw  ax
        test    ah,5
        jp      .j
  @@:
        dec     esi
        fld     [fj]
        fstp    [harg]
        fld     [fj]
        fmul    [ten]
        fstp    [fj]
        fld     [fj]
        fcomp   [one]
        fnstsw  ax
        test    ah,5
        jnp     @B
        mov     [r2],esi
        jmp     .j
  .h:
        cmp     edi,esi
        ja      .c
  @@:
        lea     eax,[ebx+BUFF_SIZE]
        cmp     edi,eax
        jae     .c
        lea     ecx,[fj]
        fld     [harg]
        fmul    [ten]
        fstp    [harg]
        stdcall _modf,double [harg],ecx
        mov     ecx,[hdecpt]
        fstp    [harg]
        fld     [fj]
        fistp   [tmp]
        mov     dl,byte [tmp]
        add     dl,'0'
        mov     [edi],dl
        inc     edi
        cmp     edi,esi
        jbe     @B
  .c:
        lea     eax,[ebx+BUFF_SIZE]
        cmp     esi,eax
        jb      @F
        mov     byte [ebx+255],0
        jmp     .out

  @@:
        mov     dl,[esi]
        add     dl,5
        mov     eax,esi
        mov     [esi],dl
        cmp     dl,'9'
        jle     .d
  .g:
        mov     byte [esi],'0'
        cmp     esi,ebx
        jbe     .e
        mov     dl,[esi-1]
        dec     esi
        inc     dl
        mov     [esi],dl
        jmp     .f
  .e:
        mov     byte [esi],'1'
        mov     edi,[ecx]
        inc     edi
        cmp     eax,ebx
        mov     [ecx],edi
        jbe     @F
        mov     byte [eax],'0'
  @@:
        inc     eax
  .f:
        cmp     byte [esi],'9'
        jg      .g
  .d:
        mov     byte [eax],0
  .out:
        mov     eax,ebx
        ret
  endp

  ; -------------------------------------------------
  ;
  ; return fractional part in st0 and integer
  ; part in y (pointer to a qword)
  ;
  ; -------------------------------------------------

  proc  _modf uses edi, x:QWORD,y
  locals
        cw1     dw ?
        cw2     dw ?
  endl
        mov     edi,[y]
        fnstcw  [cw1]
        fwait
        mov     ax,[cw1]
        or      ax,110000111111b
        mov     [cw2],ax
        fldcw   [cw2]
        fwait
        fld     [x]
        frndint
        fstp    qword [edi]
        fwait
        fld     [x]
        fsub    qword [edi]
        fldcw   [cw1]
        fwait
        ret
  endp

  ; -------------------------------------------------
  ;
  ; integer to ascii conversion (reverend)
  ;
  ; -------------------------------------------------

  proc  _itoa uses ebx esi edi, number,result_buffer
  locals
        temp_buffer                   rb 32+1
  endl

        push    10
        pop     esi
        lea     edi,[temp_buffer+32]
        mov     ebx,digits
        cmp     esi,16
        ja      .error
        std
        xor     al,al
        stosb
        mov     eax,[number]
        test    eax,80000000h
        jz      @F
        neg     eax
  @@:
        xor     edx,edx
        idiv    esi
        xchg    eax,edx
        xlatb
        stosb
        xchg    eax,edx
        test    eax,eax
        jnz     @B
        lea     esi,[edi+1]
        mov     edi,[result_buffer]
        cld
        test    [number],80000000h
        jz      @F
        mov     al,'-'
        stosb
  @@:
        lodsb
        stosb
        test    al,al
        jnz     @B
        sub     edi,[result_buffer]
        lea     eax,[edi-1]
        stc
        jmp     .theend
  .error:
        clc
  .theend:
        cld
        ret
  endp

  ; -------------------------------------------------
  ;
  ; return length of hstr string in eax (Agner Fog)
  ; pretty fast algorithm
  ;
  ; -------------------------------------------------

  proc  _strncat uses ebx esi edi, hfront,hback,hcount
        mov     esi,[hfront]
        stdcall _strlen_fog,esi
        mov     edx,eax
        add     edx,esi
        mov     edi,[hcount]
        test    edi,edi
        jz      .out_null
        mov     esi,[hback]
  @@:
        mov     cl,[esi]
        mov     [edx],cl
        dec     edi
        inc     edx
        inc     esi
        test    cl,cl
        jz      .out
        test    edi,edi
        jnz     @B
  .out_null:
        xor     al,al
        mov     byte [edx],al
  .out:
        ret
  endp

  ; -------------------------------------------------
  ;
  ; return length of hstr string in eax (Agner Fog)
  ; pretty fast algorithm
  ;
  ; -------------------------------------------------

  proc  _strlen_fog uses ebx esi edi, hstr
        mov     eax,[hstr]
        lea     edx,[eax+3]
  @@:
        mov     ebx,[eax]
        add     eax,4
        lea     ecx,[ebx-01010101h]
        not     ebx
        and     ecx,ebx
        and     ecx,80808080h
        jz      @B
        test    ecx,00008080h
        jnz     @F
        shr     ecx,16
        add     eax,2
  @@:
        shl     cl,1
        sbb     eax,edx
        ret
  endp

  ; -------------------------------------------------
  ;
  ; fast memory copying algorithm (tuned asmpack ver)
  ; qword -> dword -> byte
  ;
  ; -------------------------------------------------

  proc  _memcpy_fast uses esi edi, hdst,hsrc,hsize
        mov     eax,[hsize]
        mov     edi,[hdst]
        mov     esi,[hsrc]
        mov     ecx,eax
        shr     ecx,3
        jz      .next1
  @@:
        movq    mm0,qword [esi]
        movq    qword [edi],mm0
        add     esi,8
        add     edi,8
        dec     ecx
        jnz     @B
  .next1:
        mov     ecx,eax
        and     ecx,7
        shr     ecx,2
        jz      .next2
  @@:
        mov     edx,[esi]
        mov     [edi],edx
        add     esi,4
        add     edi,4
        dec     ecx
        jnz     @B
  .next2:
        and     eax,3
        jz      .out
  @@:
        mov     dl,byte [esi]
        mov     byte [edi],dl
        inc     esi
        inc     edi
        dec     eax
        jnz     @B
  .out:
        sub     edi,[hsize]
        mov     eax,edi
        ret
  endp

section '.idata' import data readable writeable

  library       kernel32,'kernel32.dll',\
                user32,'user32.dll',\
                gdi32,'gdi32.dll',\
                comdlg32,'comdlg32.dll',\
                advapi32,'advapi32.dll'

  include       '..\include\api\kernel32.inc'
  include       '..\include\api\user32.inc'
  include       '..\include\api\gdi32.inc'
  include       '..\include\api\comdlg32.inc'
  include       '..\include\api\advapi32.inc'

; eof    


the problem is it shows something else instead of 0.0030000
Post 16 Sep 2012, 18:01
View user's profile Send private message Yahoo Messenger Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Masood.Sandking,

You're storing dword in figure1 and trying to pass it as double (i.e. qword) to _ftoa().
Post 18 Sep 2012, 06:56
View user's profile Send private message Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
thanks.
is there any other word instead of double...? i tried to use single or half but they are undefined...
Post 18 Sep 2012, 08:30
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17279
Location: In your JS exploiting you and your system
revolution
Masood.Sandking wrote:
thanks.
is there any other word instead of double...? i tried to use single or half but they are undefined...
Just leave it blank to pass a single.

However your _ftoa proc will likely fail if you pass the wrong sized parameters. If it expects a double then instead you should convert the single (dd) to a double (dq) first and then pass the double to _ftoa.
Post 18 Sep 2012, 08:34
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.