I could have sworn i posed this a while back but i cant find it even with the search. anyway the old version had a serious error where numbers with a fractional component around one hundred millionth were scrambled by an mistake on my part where i stored the working exponent in a 32 bit var. anyway i solved that problem and a few other minor ones.
and yes this one gives a correct return for pi = 3.1415926535897932384 (further digits have no effect.)
FORMAT PE GUI 4.0
ENTRY Start
include 'win32a.inc'
MAXTEXT = 255
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+1
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, multiplyer:TBYTE
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]
fldz
xor eax, eax
mov eax, 1
cmp BYTE [SS:ebx], '-'
jnz @f
mov eax, -1
inc ebx
@@:
push eax
;fldz
.ipart:
cmp BYTE [SS:ebx], '.'
jz .fpart0
cmp BYTE [SS:ebx], 0
jz .fin
;mov [temp], 10
;fild [temp]
fimul [const10]
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
lea ecx, [multiplyer]
fld1
fstp tbyte [ecx]
.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 ;<==== error here
;mul ecx
;mov ecx, eax
;mov [temp], ecx
;mov [temp], 10
fld TBYTE [ecx]
fidiv [const10]
fstp TBYTE [ecx]
fld TBYTE [ecx]
fild [temp]
fmulp st1, st0
faddp st1, st0
inc ebx
jmp .fpart1
.fin:
;fldpi ;test
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
;fldpi ;test
fstp TBYTE [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+1
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
"
.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'
const10 dd 10
section '.data?' data readable writable
hInstance dd ?
proc_edit dd ?
hWndDlg dd ?
iFloatType dd ?