flat assembler
Message board for the users of flat assembler.

Index > Windows > Floating point hex converter

Author
Thread Post new topic Reply to topic
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
I was having troubble inputing Floating point values into FASM so i Created a floating point number to hex number converter. i've found it usefull for OpenGL .
Code:
FORMAT PE GUI 4.0
ENTRY  Start

include 'win32a.inc'

MAXTEXT = 40

section '.idata' import data readable writeable
  library     kernel32,           'kernel32.dll',\
              user32,             'user32.dll'

  import      kernel32,\
              GetModuleHandle,    'GetModuleHandleA',\
              ExitProcess,        'ExitProcess';,\

  import      user32,\
              SendMessage,        'SendMessageA',\
              PostMessage,        'PostMessageA',\
              DialogBoxParam,     'DialogBoxParamA',\
              SendDlgItemMessage, 'SendDlgItemMessageA',\
              GetDlgItem,         'GetDlgItem',\
              EndDialog,          'EndDialog',\
              SetWindowLong,      'SetWindowLongA',\
              CallWindowProc,     'CallWindowProcA',\
              MessageBox,         'MessageBoxA'

section '.code' code readable executable

proc fltedit_proc, hwnd, msg, wparam, lparam
  cmp   [msg], WM_CHAR
  jnz  .norm
  mov   eax, [wparam]
  cmp   ax, 00008h
  jz   .norm
  cmp   ax, '-'
  jz   .negitive
  cmp   ax, '.'
  jz   .decmal
  cmp   ax, '0'
  jl   .leave
  cmp   ax, '9'
  jg   .leave
 .norm:
  push  [lparam]
  push  [wparam]
  push  [msg]
  push  [hwnd]
  push  [proc_edit]
  call  [CallWindowProc]
 .leave:
  ret
 .negitive:
  push  0
  push  0
  push  EM_GETSEL
  push  [hwnd]
  call  [SendMessage]
  cmp   ax, 0
  jz   .norm
  jmp  .leave
 .decmal:
  push  [wparam]
  push  [hwnd]
  call  scan
  cmp   eax, 0
  jz   .leave
  jmp  .norm
endp

proc scan, hwnd:DWORD, char:DWORD
  local fltstring[MAXTEXT+1]:BYTE
  push  ebx
  push  ecx
  push  edx

  lea   ebx, [fltstring]
  push  ebx
  push  MAXTEXT
  push  WM_GETTEXT
  push  [hwnd]
  call  [SendMessage]

  xor   ecx, ecx
  xor   eax, eax
 .loop:
  inc   ecx
  cmp   BYTE [SS:ebx+ecx-1], 0
  jz   .test
  cmp   BYTE [SS:ebx+ecx-1], '.'
  jnz  .loop
  inc   eax
  jmp  .loop

 .test:
  mov   edx, [char]
  cmp   dx, '.'
  jnz  .bad
  cmp   eax, 0
  jz   .good
 .bad:
  xor   eax, eax
  jmp  .end
 .good:
  mov   eax, 1
 .end:
  pop   edx
  pop   ecx
  pop   ebx
  ret
endp

;section no longer needed due to checks in above subclass
;proc finddec, strptr:DWORD

proc flttovalue, string:DWORD, value:DWORD;, decimal:DWORD
  local  temp:DWORD, cword:WORD
  push  ebx
  push  ecx
  mov   ebx, [string]
  finit
  ;fstcw [cword]
  ;mov   ax, [cword]
  ;or    ax, 00300h
  ;and   ax, 0F3FFh
  ;mov   [cword], ax
  ;fldcw [cword]
  mov   [temp], 0
  fild  [temp]
  xor   eax, eax
  mov   eax, 1
  cmp   BYTE [SS:ebx], '-'
  jnz   @f
  mov   eax, -1
  inc   ebx
 @@:
  push  eax
 .ipart:
  cmp   BYTE [SS:ebx], '.'
  jz   .fpart0
  cmp   BYTE [SS:ebx], 0
  jz   .fin
  mov   [temp], 10
  fild  [temp]
  fmulp st1, st0
  xor   eax, eax
  mov   al, BYTE [SS:ebx]
  sub   al, '0'
  mov   [temp], eax
  fild  [temp]
  faddp st1, st0
  inc   ebx
  jmp  .ipart
 .fpart0:
  inc   ebx
  mov   ecx, 1
 .fpart1:
  cmp   BYTE [SS:ebx], '.'
  jz   .fin
  cmp   BYTE [SS:ebx], 0
  jz   .fin
  xor   eax, eax
  mov   al, BYTE [SS:ebx]
  sub   al, '0'
  mov   [temp], eax
  fild  [temp]
  mov   eax, 10
  mul   ecx
  mov   ecx, eax
  mov   [temp], ecx
  fild  [temp]
  fdivp st1, st0
  faddp st1, st0
  inc   ebx
  jmp  .fpart1
 .fin:
  pop   eax
  mov   [temp], eax
  fild  [temp]
  fmulp st1, st0
  ;fstcw [cword]
  ;mov   ax, [cword]
  ;mov   cx, WORD [iFloatType]
  ;shl   cx, 8
  ;or    cx, 0F0FFh
  ;and   ax, cx
  ;mov   [cword], ax
  ;fldcw [cword]
  mov   eax, [value]
  mov   edx, [iFloatType]
  cmp   edx, const80
  jnz   @f
  fstp  TWORD [eax]
 @@:
  cmp   edx, const64
  jnz   @f
  fstp  QWORD [eax]
 @@:
  cmp   edx, const32
  jnz   @f
  fstp  DWORD [eax]
 @@:
  mov   eax, esi
  pop   ecx
  pop   ebx
  ret
endp

proc valuetostr, string:DWORD, value:DWORD
  push  ebx
  push  ecx
  push  edx
  push  esi
  mov   edx, [iFloatType]
  mov   ecx, 10
  cmp   edx, const80
  jz   .start
  mov   ecx, 8
  cmp   edx, const64
  jz   .start
  mov   ecx, 4
  cmp   edx, const32
  jz   .start
  xor   ecx, ecx
  xor   eax, eax
  jmp  .end
 .start:
  mov   esi, [string]
  mov   edx, [value]
  mov   ebx, hexcharset
  xor   eax, eax
 .next:
  mov   al, [edx+ecx-1]
  shr   al, 4
  and   al, 0fh
  mov   al, [ebx + eax]
  mov   [esi], al
  inc   esi
  mov   al, [edx+ecx-1]
  and   al, 0fh
  mov   al, [ebx + eax]
  mov   [esi], al
  inc   esi
  ;inc   edx
  dec   ecx
  jnz  .next
  mov   BYTE [esi], 0
 .end:
  pop   esi
  pop   edx
  pop   ecx
  pop   ebx
  ret
endp

proc  flttohex, hWndFlt:DWORD, hWndHex:DWORD
  local fltstring[MAXTEXT+1]:BYTE, hexstring[21]:BYTE, fltVlaue:TBYTE
  lea   eax, [fltstring]
;  push  eax
  push  eax
  push  MAXTEXT
  push  WM_GETTEXT
  push  [hWndFlt]
  call  [SendMessage]
  cmp   eax, 0
  jz   .blank
;  call  finddec
  cmp   eax, -1
  jz   .badvalue
 ; int   3
 ; push  eax
  lea   eax, [fltVlaue]
  push  eax
  lea   eax, [fltstring]
  push  eax
  call  flttovalue

  lea   eax, [fltVlaue]
  push  eax
  lea   eax, [hexstring]
  push  eax
  call  valuetostr
  cmp   eax, 0
  jz   .badvalue

  lea   eax, [hexstring]
  push  eax
  push  0
  push  WM_SETTEXT
  push  [hWndHex]
  call  [SendMessage]
  ret

 .blank:
  push  fltblank
  push  0
  push  WM_SETTEXT
  push  [hWndHex]
  call  [SendMessage]
  ret

 .badvalue:
  push  flterror
  push  0
  push  WM_SETTEXT
  push  [hWndHex]
  call  [SendMessage]
  ret
endp
;flterror
;fltblank

proc  command, hdlg, wparam, lparam
  mov  eax, [wparam]
  shr  eax, 16
  and  eax, 0FFFFh
  cmp  eax, EN_CHANGE
  jnz  @f
    mov  eax, [wparam]
    and  eax, 0FFFFh
    cmp  eax, IDI_FLOATNUMBER
    jz  .fltcnvt
    jmp .badcmd
 @@:
  cmp  eax, BN_CLICKED
  jnz  @f
    mov  eax, [wparam]
    and  eax, 0FFFFh
    cmp  eax, IDI_FLOAT32
    jz  .flt32
    cmp  eax, IDI_FLOAT64
    jz  .flt64
    cmp  eax, IDI_FLOAT80
    jz  .flt80
    cmp  eax, IDI_EXIT
    jz  .exit
 @@:
 .badcmd:
  xor  eax, eax
  ret

db "FrozenKnight's Signiture",0B6h,\
   "this program is provided as a ",\
   "tool for your use. Free of charge. ",\
   "Please don't steal my hard work or ",\
   "or cheat others out of it. Thank You Smile"
 .fltcnvt:
  push IDI_HEXNUMBER
  push [hdlg]
  call [GetDlgItem]
  push eax
  push IDI_FLOATNUMBER
  push [hdlg]
  call [GetDlgItem]
  push eax
  call flttohex
  xor  eax, eax
  ret

 .flt32:
  push  0
  push  1
  push  BM_SETCHECK
  push  IDI_FLOAT32
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT64
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT80
  push  [hdlg]
  call  [SendDlgItemMessage]

  mov   [iFloatType], const32
  jmp  .fltcnvt

 .flt64:
  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT32
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  1
  push  BM_SETCHECK
  push  IDI_FLOAT64
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT80
  push  [hdlg]
  call  [SendDlgItemMessage]

  mov   [iFloatType], const64
  jmp  .fltcnvt

 .flt80:
  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT32
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  0
  push  BM_SETCHECK
  push  IDI_FLOAT64
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  1
  push  BM_SETCHECK
  push  IDI_FLOAT80
  push  [hdlg]
  call  [SendDlgItemMessage]

  mov   [iFloatType], const80
  jmp  .fltcnvt

 .exit:
  push  0
  push  dword [hdlg]
  call  [EndDialog]
  xor   eax,eax
  ret
endp

proc  dlg_proc, hdlg, msg, wparam, lparam
  mov   eax, [msg]
  cmp   eax, WM_COMMAND
  jz   .command
  cmp   eax, WM_INITDIALOG
  jz   .initdlg
  cmp   eax, WM_CLOSE
  jz   .wmclose
  xor   eax,eax
  ret

 .command:
  push  [lparam]
  push  [wparam]
  push  [hdlg]
  call  command
  ret

 .initdlg:
  push  [hdlg]
  pop   [hWndDlg]

  push  0
  push  1
  push  EM_SETREADONLY
  push  IDI_HEXNUMBER
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  MAXTEXT
  push  EM_LIMITTEXT
  push  IDI_FLOATNUMBER
  push  [hdlg]
  call  [SendDlgItemMessage]

  push  0
  push  1
  push  BM_SETCHECK
  push  IDI_FLOAT64
  push  [hdlg]
  call  [SendDlgItemMessage]
  mov   [iFloatType], const64

  ;subclass float field to prevent unwanted charicters from being input
  push  IDI_FLOATNUMBER
  push  [hdlg]
  call  [GetDlgItem]
  push  fltedit_proc
  push  GWL_WNDPROC
  push  eax
  call  [SetWindowLong]
  cmp   eax, 0
  jz    .wmclose
  mov   [proc_edit], eax
  xor   eax, eax
  ret

.wmclose:  ;close button or <alt>+<f4>
  push  0
  push  dword [hdlg]
  call  [EndDialog]
  xor   eax,eax
  ret
endp

Start:
  push   0
  call   [GetModuleHandle]   ;get handel to program instance
  mov    [hInstance], eax
  push   0
  push   dlg_proc
  push   HWND_DESKTOP
  push   IDD_MAINDIALOG
  push   eax
  call   [DialogBoxParam] ;create dialog
  push   0
  call   [ExitProcess]
  mov    eax, flttovalue


section '.rsrc' resource data readable

  IDD_MAINDIALOG  = 01000h
  IDI_FLOATNUMBER = 00101h
  IDI_HEXNUMBER   = 00102h
  IDI_EXIT        = 00201h
  IDI_FLOAT32     = 00301h
  IDI_FLOAT64     = 00302h
  IDI_FLOAT80     = 00303h

  const32         = 00h
  const64         = 02h
  const80         = 03h

  directory RT_DIALOG, dialogs

  resource dialogs,\
           IDD_MAINDIALOG, LANG_ENGLISH+SUBLANG_DEFAULT, maindialog

  dialog maindialog, 'Float=>Hex Converter', CW_USEDEFAULT, CW_USEDEFAULT,\
                     202, 67, DS_MODALFRAME or WS_POPUP or WS_CAPTION or WS_SYSMENU
    dialogitem 'EDIT', '', IDI_FLOATNUMBER, 24, 10, 166, 12,\
               ES_CENTER or WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_BORDER or ES_AUTOHSCROLL
    dialogitem 'EDIT', '', IDI_HEXNUMBER, 24, 30, 166, 12,\
               ES_CENTER or WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_BORDER
    dialogitem 'STATIC', 'Float', 0, 5, 11, 19, 10,\
               SS_LEFT or WS_CHILD or WS_VISIBLE
    dialogitem 'STATIC', 'Hex', 0, 7, 32, 15, 10,\
               SS_LEFT or WS_CHILD or WS_VISIBLE
    dialogitem 'BUTTON', '32', IDI_FLOAT32, 39, 47, 26, 14,\
               BS_RADIOBUTTON or WS_CHILD or WS_VISIBLE or WS_TABSTOP
    dialogitem 'BUTTON', '64', IDI_FLOAT64, 65, 47, 26, 14,\
               BS_RADIOBUTTON or WS_CHILD or WS_VISIBLE or WS_TABSTOP
    dialogitem 'BUTTON', '80', IDI_FLOAT80, 89, 47, 26, 14,\
               BS_RADIOBUTTON or WS_CHILD or WS_VISIBLE or WS_TABSTOP
    dialogitem 'BUTTON', '&Exit', IDI_EXIT, 129, 47, 60, 14,\
               BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE or WS_TABSTOP
  enddialog


section '.const' data readable
  flterror       db  '<Error: Unable to convert>',0
  fltblank       db  '',0
  hexcharset     db  '0123456789ABCDEF'

section '.data?' data readable writable
  hInstance      dd  ?
  proc_edit      dd  ?
  hWndDlg        dd  ?
  iFloatType     dd  ?    


Last edited by FrozenKnight on 10 Aug 2006, 10:45; edited 1 time in total
Post 26 Oct 2005, 21:50
View user's profile Send private message Reply with quote
Jack



Joined: 16 Feb 2005
Posts: 21
Jack
try inputing 3.1415926535897932384626433832795 your prog shows 4000C90FDA912CE9480B when it should 4000C90FDAA22168C23(4)
Post 27 Oct 2005, 11:28
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
And when you do
Code:
dt 3.1415926535897932384626433832795    
in fasm you get the 4000C90FDAA22168C235h. What was that trouble you had with inputing fp values into fasm?
Post 27 Oct 2005, 12:22
View user's profile Send private message Visit poster's website Reply with quote
Jack



Joined: 16 Feb 2005
Posts: 21
Jack
sorry for the late reply Tomasz, I did not compile the source but used the executable to test.
Post 27 Oct 2005, 23:31
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
have ypu tried pushing hta value onto the stack as a constant?
Post 28 Oct 2005, 10:27
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
Push as what type of fp value? You can push 32-bit one freely, for the 64-bit there's no single instruction that would do it for you, but you can use the "double" feature of extended "invoke" (read this!)

As for the 80-bit values that were shown above, there is also no instruction that would push the on the stack for you. If for some reason you really want to push the "tbyte" value on the stack, you can do it this way:
Code:
macro pusht value
{ virtual at 0
  dt value
  local lo,mid,hi
  load lo dword from 0
  load mid dword from 4
  load hi word from 8
 end virtual
 push word hi
 push dword mid
 push dword lo }

; example:
pusht 3.1415926535897932384626433832795    

Of course you can easily adapt it for 64-bits if the "double" feature is not enough for you.


Last edited by Tomasz Grysztar on 28 Oct 2005, 13:32; edited 2 times in total
Post 28 Oct 2005, 12:16
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
The macro is correct? It's pushing 6 bytes instead of 10.

(I'm not correcting you, I just don't sure about this)

[edit]
Code:
format PE GUI 4.0
entry start

macro pusht value
{ virtual at 0
  dt value
  local lo, mid, hi             ; Now added "mid"
  load lo  dword from 0
  load mid dword from 4
  load hi  word  from 8
 end virtual
 push word  hi
 push dword mid
 push dword lo }

; example:
start:
pusht   3.1415926535897932384626433832795
add     esp, 10
ret     
[/edit]

[edit]Better I corrected the locals to not confuse nobody[/edit]


Last edited by LocoDelAssembly on 28 Oct 2005, 17:50; edited 2 times in total
Post 28 Oct 2005, 13:18
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
Oh, you're right. Corrected it. Wink
Post 28 Oct 2005, 13:31
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
jajajajaja, both corrected this at the same time Razz
[edit] all of you use the Tomasz's code, I forgot to put mid on local[/edit]
Post 28 Oct 2005, 13:36
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
I'm not too familar with the macro's yet, and as such i'm a little reculant to use them at times. currently i perfer.
Code:
push 040091EB8h
push 051EB851Fh ;3.14( i was too lazy to try that whole long decimal becidedes i know a better way to get pi from the fpu    


BTW is there someone who knows where i can find a turt for useing FASM macros? i'm having a little troubble understanding them.
Post 28 Oct 2005, 16:05
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
The shortest sample without macros:
Code:
virtual at 0
 dq 3.14
 load low dword from 0
 load high dword from 4
end virtual

push high
push low    
(does the same what your)

Hope this example helps you understand how fasm's assembler module facilities work (the macros themselves are something different, the macro posted earlier was designed just to automatically generate such sequence of assembler commands like the above).
Post 28 Oct 2005, 19:28
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt
question about the virual macro code, does the virtual macro generate any code? or maybe just temporary code?
Post 28 Oct 2005, 22:23
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
"virtual" is not a macro, it's assembler's directive. Everything inside the "virtual" block is not put into output file, but it is generated as a temporary code in memory just for the time of assembly (so you can load values like here).
Post 28 Oct 2005, 22:40
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt
Allright, I understand now, thanks. Smile
Post 29 Oct 2005, 05:07
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
Thanks Tomasz Grysztar that is what i have been trying to figure out.
i really need to learn these precompiler directive and macros.

i wish someone would make a turtorial on the macros becasue they are really confuseing as they are.
Post 05 Nov 2005, 05:11
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
I know this post is kind of old but i was wondering why my program gives a diffrent value for 3.1415926535897932384626433832795 (4000C90FDA912CE9480B) than the fldpi (4000C90FDAA22168C235) or the value in fasm. this is a small problem that has confused me reciently.
Post 26 Aug 2006, 22:26
View user's profile Send private message Reply with quote
UCM



Joined: 25 Feb 2005
Posts: 285
Location: Canada
UCM
Probably it's because the "fldpi" has more/less accuraccy in the mantissa.
Post 26 Aug 2006, 22:36
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
maybe also because of inaccurate conversion routine of FASM
Post 27 Aug 2006, 09:18
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
fasm fed with "3.1415926535897932384626433832795" string gives the same value as FLDPI. Its conversions are quite accurate, since it uses internally 128-bit floating point format to do the calculations.
Post 31 Aug 2006, 09:06
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:  


< 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 GitHub, YouTube, Twitter.

Website powered by rwasa.