.NOLIST
.NOCREF
.586
.MMX
.model flat,stdcall
option casemap:none
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib

 WM_CASE macro reg,msgs
 irp msg,<msgs>
	cmp reg,WM_&msg
	je @@&msg
 endm
endm
hInstance equ 400000h
.code
DlgProc proc uses ebx edi esi hWnd,uMsg,wParam,lParam
	mov eax,uMsg
	mov esi,hWnd
	WM_CASE eax,<INITDIALOG,CLOSE,COMMAND>
@r0:	xor eax,eax
@r:	ret
@@INITDIALOG:
	invoke LoadIcon,400000h,200
	invoke SetClassLong,esi,GCL_HICON,eax
	jmp @r
@@CLOSE:
	invoke EndDialog,esi,eax
	jmp @r
@@COMMAND:
	cmp wParam,2
	je @@CLOSE
	jnc @r
;Get integer
.data?
failed dd ?
.code
	invoke GetDlgItemInt,esi,13,offset failed,0
	test eax,eax
	je @DivBy0
	js @Signed
		
;
;Получить
;1. Magic
;2. Shift
.data?
shift dd ?
r dq ?
ldivider dq ?
magic dq ?
.code
	mov eax,eax
	bsr ecx,eax	;получим b - индекс старшего значимого байта
	lea edx,[eax-1]
	mov edi,offset r
	test eax,edx
	je @powerof2 
	xor edx,edx
	mov [shift],ecx
	mov  [edi],edx
	mov  [edi+12],edx
	inc edx
	mov [edi+8],eax
	shl edx,cl
	mov [edi +4],edx

	fild qword ptr [edi]		;загрузим 2^(b+32)
	fild qword ptr [edi+8]

	fdivp st(1),st(0)
	fst st(1)		;сохраним результат в st1 для сравнения с округлённым
	fistp [magic]	;сохраним magic
	fild [magic]	;загрузм его для сравнения
	fcompp		;выкинем оба из стека сравнив
	fstsw ax		;
	push eax
.data
msgp2 db 'Divider is power of 2',13,10
db	 'To divide X by the divider use:',13,10
 db'mov edx,X',13,10
shiftstr db 'SHR edx, '
bstring db 12 dup (?)

StrMagic db 'MagicNumber = '
MagicNumber db 12 dup (?)

AlgoStringB db 13,10
	db 'mov eax,X',13,10
	db 'mov edx, MagicNumber',13,10
	db 'inc eax',13,10
	db 'mul edx',13,10,0

AlgoStringC db 13,10
	db 'mov eax,X',13,10
	db 'mov edx, MagicNumber',13,10
	db 'mul edx',13,10,0
.data?
buffer db 1024 dup (?)
.code
	invoke udw2str,shift,offset bstring
	invoke udw2str,dword ptr magic,offset MagicNumber
	pop eax
	sahf		;загрузим результат сравнения в флаги
	mov edi,offset AlgoStringB
	jbe @lower
	mov edi,offset AlgoStringC
@lower:
	mov buffer,0
	invoke szMultiCat,3,offset buffer,offset StrMagic,edi,offset shiftstr
	invoke SetDlgItemText,esi,11,offset buffer

	jmp @r
@powerof2:
	invoke udw2str,ecx,offset bstring
	invoke SetDlgItemText,esi,11,offset msgp2
	jmp @r
@DivBy0:
.data
msgerr db 'Specifyed number is invalid',0
.code
	invoke MessageBox,esi,offset msgerr,0,0
	invoke SetDlgItemText,esi,11,0
	jmp @r
@Signed:

.data
sAlgo	db '	mov eax,X',13,10
	db '	mov edx,1',13,10
	db '	cmp eax,divider',13,10
	db '	sbb edx,0',0
.code
	invoke SetDlgItemText,esi,11,offset sAlgo
	jmp @r
.data
sbAlgo	db '	mov eax,divider',13,10
	db '	mov ecx,X',13,10
	db '	xor edx,edx',13,10
	db '@@:	sub ecx,eax',13,10
	db '	inc edx',13,10
	db '	jnc @B',13,10
	db '	dec edx',13,10,0
.code
@subAlgo:
	invoke SetDlgItemText,esi,11,offset sbAlgo
	jmp @r

DlgProc endp
start:
	invoke DialogBoxParam,hInstance,6,0,offset DlgProc,0
	call ExitProcess
	end start