flat assembler
Message board for the users of flat assembler.

Index > Windows > CreateWindowEx trashes floating point control word

Author
Thread Post new topic Reply to topic
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
Before calling CreateWindowEx I have the control word set to 64 bit precision, and when the function returns, it is changed back to 53 bits. Is this usual behavio? or am I doing something wrong?
Post 20 Jan 2012, 01:32
View user's profile Send private message Reply with quote
Yardman



Joined: 12 Apr 2005
Posts: 245
Location: US
Yardman
[ Post removed by author. ]


Last edited by Yardman on 04 Apr 2012, 04:50; edited 1 time in total
Post 20 Jan 2012, 04:23
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
OK. The problem disappears if I load the msvcrt.dll to print the string. Maybe windows recognizes that this is loaded and changes some functionality?
What is get for the control word is:
1111111011 before the call
1111111001 after the call
Why is it messing with it?

Code:
; Simple text editor - fasm example program

format PE GUI 4.0
entry start

include 'win32a.inc'

IDM_NEW   = 101
IDM_EXIT  = 102
IDM_ABOUT = 901

section '.text' code readable executable

  start:

        mov     word[esp-2],0x037F
        fldcw   word[esp-2]

        fstcw   word[cw]
;        invoke  sprintf,message,messageformat,[cw]
        mov     edi,message
        mov     cx,word[cw]
   @@:  mov     al,'0'
        shr     cx,1
        adc     al,0
        stosb
        test    cx,cx
        jnz     @b
        mov     al,0
        stosb

        invoke  MessageBox,NULL,message,NULL,MB_OK



        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,eax,17
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  LoadMenu,[wc.hInstance],37
        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,[wc.hInstance],NULL
        test    eax,eax
        jz      error

        fstcw   word[cw]
;        invoke  sprintf,message,messageformat,[cw]
        mov     edi,message
        mov     cx,word[cw]
   @@:  mov     al,'0'
        shr     cx,1
        adc     al,0
        stosb
        test    cx,cx
        jnz     @b
        mov     al,0
        stosb

        invoke  MessageBox,NULL,message,NULL,MB_OK



  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp     [wmsg],WM_CREATE
        je      .wmcreate
        cmp     [wmsg],WM_SIZE
        je      .wmsize
        cmp     [wmsg],WM_SETFOCUS
        je      .wmsetfocus
        cmp     [wmsg],WM_COMMAND
        je      .wmcommand
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmcreate:
        invoke  GetClientRect,[hwnd],client
        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,_edit,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[client.left],[client.top],[client.right],[client.bottom],[hwnd],0,[wc.hInstance],NULL
        or      eax,eax
        jz      .failed
        mov     [edithwnd],eax
        invoke  CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
        or      eax,eax
        jz      .failed
        mov     [editfont],eax
        invoke  SendMessage,[edithwnd],WM_SETFONT,eax,FALSE
        xor     eax,eax
        jmp     .finish
      .failed:
        or      eax,-1
        jmp     .finish
  .wmsize:
        invoke  GetClientRect,[hwnd],client
        invoke  MoveWindow,[edithwnd],[client.left],[client.top],[client.right],[client.bottom],TRUE
        xor     eax,eax
        jmp     .finish
  .wmsetfocus:
        invoke  SetFocus,[edithwnd]
        xor     eax,eax
        jmp     .finish
  .wmcommand:
        mov     eax,[wparam]
        and     eax,0FFFFh
        cmp     eax,IDM_NEW
        je      .new
        cmp     eax,IDM_ABOUT
        je      .about
        cmp     eax,IDM_EXIT
        je      .wmdestroy
        jmp     .defwndproc
      .new:
        invoke  SendMessage,[edithwnd],WM_SETTEXT,0,0
        jmp     .finish
      .about:
        invoke  MessageBox,[hwnd],_about_text,_about_title,MB_OK
        jmp     .finish
  .wmdestroy:
        invoke  DeleteObject,[editfont]
        invoke  PostQuitMessage,0
        xor     eax,eax
  .finish:
        pop     edi esi ebx
        ret
endp


section '.data' data readable writeable

  _title TCHAR 'MiniPad',0
  _about_title TCHAR 'About MiniPad',0
  _about_text TCHAR 'This is Win32 example program created with flat assembler.',0
  _error TCHAR 'Startup failed.',0



  _class TCHAR 'MINIPAD32',0
  _edit TCHAR 'EDIT',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  edithwnd dd ?
  editfont dd ?

  msg MSG
  client RECT


rb 100
align 4
  cw dd 0
  message rb 100
  messageformat db 'control word: 0x%.8X',0,0


section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          gdi,'GDI32.DLL';,\
          ;msvcrt,'MSVCRT.DLL'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess'

  import user,\
         RegisterClass,'RegisterClassA',\
         CreateWindowEx,'CreateWindowExA',\
         DefWindowProc,'DefWindowProcA',\
         SetWindowLong,'SetWindowLongA',\
         RedrawWindow,'RedrawWindow',\
         GetMessage,'GetMessageA',\
         TranslateMessage,'TranslateMessage',\
         DispatchMessage,'DispatchMessageA',\
         SendMessage,'SendMessageA',\
         LoadCursor,'LoadCursorA',\
         LoadIcon,'LoadIconA',\
         LoadMenu,'LoadMenuA',\
         GetClientRect,'GetClientRect',\
         MoveWindow,'MoveWindow',\
         SetFocus,'SetFocus',\
         MessageBox,'MessageBoxA',\
         PostQuitMessage,'PostQuitMessage'

  import gdi,\
         CreateFont,'CreateFontA',\
         DeleteObject,'DeleteObject'

;  import msvcrt,\
;         sprintf,'sprintf'

section '.rsrc' resource data readable

  ; resource directory

  directory RT_MENU,menus,\
            RT_ICON,icons,\
            RT_GROUP_ICON,group_icons,\
            RT_VERSION,versions

  ; resource subdirectories

  resource menus,\
           37,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu

  resource icons,\
           1,LANG_NEUTRAL,icon_data

  resource group_icons,\
           17,LANG_NEUTRAL,main_icon

  resource versions,\
           1,LANG_NEUTRAL,version

  menu main_menu
       menuitem '&File',0,MFR_POPUP
                menuitem '&New',IDM_NEW
                menuseparator
                menuitem 'E&xit',IDM_EXIT,MFR_END
       menuitem '&Help',0,MFR_POPUP + MFR_END
                menuitem '&About...',IDM_ABOUT,MFR_END

  icon main_icon,icon_data,'minipad.ico'

  versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
              'FileDescription','MiniPad - example program',\
              'LegalCopyright','No rights reserved.',\
              'FileVersion','1.0',\
              'ProductVersion','1.0',\
              'OriginalFilename','MINIPAD.EXE'
    
Post 20 Jan 2012, 06:52
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 294
Alphonso
Which OS are you running this on?

I get 1111111011 both before and after with VHP SP2 32-bit and W7HP SP1 64-bit
Post 20 Jan 2012, 09:55
View user's profile Send private message Reply with quote
Yardman



Joined: 12 Apr 2005
Posts: 245
Location: US
Yardman
[ Post removed by author. ]


Last edited by Yardman on 04 Apr 2012, 04:50; edited 1 time in total
Post 20 Jan 2012, 10:53
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 294
Alphonso
No problem with Vista.


Description: Start
Filesize: 11.38 KB
Viewed: 2135 Time(s)

1a.png


Description: MBox1
Filesize: 14.87 KB
Viewed: 2135 Time(s)

2a.png


Description: MBox2
Filesize: 14.82 KB
Viewed: 2135 Time(s)

3a.png


Post 20 Jan 2012, 13:30
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
I would not rely on API to preserve anything from FPU point of view. If I had some calculations to make - I would write a function which does all setup of precision or whatever, also 'finit' to be sure - all before real calculation begins. It is known that API uses MMX (which are the same as FPU registers), so why it can't use FPU control word?
Post 20 Jan 2012, 15:18
View user's profile Send private message Send e-mail Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 619
cod3b453
I think this is a general issue under NT, which forces precision down to 64bit/53bit mantissa -- probably during some interrupt or syscall, so not very deterministic. Question
Post 20 Jan 2012, 18:30
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
0x3F7 both times with Yardman's code in Windows 7 Home Premium 64-bit.
Post 20 Jan 2012, 19:52
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
It happened to me on XP sp 3, but I'm glad its nothing that I am doing wrong. I just won't expect windows to preserve certain things.
Post 20 Jan 2012, 20:21
View user's profile Send private message Reply with quote
Yardman



Joined: 12 Apr 2005
Posts: 245
Location: US
Yardman
[ Post removed by author. ]


Last edited by Yardman on 04 Apr 2012, 04:51; edited 1 time in total
Post 20 Jan 2012, 20:56
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Agner Fog wrote:
Floating point control word and MXCSR register
The floating point control word and bit 6-15 of the MXCSR register must be saved and
restored before any call or return by any procedure that needs to modify them, except for
procedures that have the purpose of changing these.
Does anyone has the official Microsoft's documentation backing up this (which looks pretty reasonable, but yet it might be wrong)?
Post 20 Jan 2012, 21:48
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Mmmhhh, maybe this explains why is this happening?

Have you tried setting the control word to the minimum precision to see if it is also reset to Windows' default?
Post 20 Jan 2012, 21:53
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 619
cod3b453
LocoDelAssembly wrote:
Mmmhhh, maybe this explains why is this happening?

Have you tried setting the control word to the minimum precision to see if it is also reset to Windows' default?
One up frorm there at http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx , it says:
Quote:
By default, _controlfp's precision control is set to 53 bits (_PC_53). Linking with FP10.OBJ changes the default precision control to 64 bits (_PC_64). On the linker command line, FP10.OBJ must appear before LIBC.LIB, LIBCMT.LIB, or MSVCRT.LIB.
which soudns like it matches what tthsqe said
Post 20 Jan 2012, 22:30
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 294
Alphonso
tthsqe wrote:
It happened to me on XP sp 3, but I'm glad its nothing that I am doing wrong. I just won't expect windows to preserve certain things.
I tried it on XP SP3 and... it worked fine also.


This is a little obscure so not sure how pertinent it is.
Quote:
The register state also includes the x87 FPU control word. The calling convention dictates this register to be nonvolatile.

The x87 FPU control word register is set to the following standard values at the start of program execution:

FPCSR[0:6]: Exception masks all 1's (all exceptions masked)
FPCSR[7]: Reserved – 0
FPCSR[8:9]: Precision Control – 10B (double precision)
FPCSR[10:11]: Rounding control - 0 (round to nearest)
FPCSR[12]: Infinity control – 0 (not used)

A callee that modifies any of the fields within FPCSR must restore them before returning to its caller. Furthermore, a caller that has modified any of these fields must restore them to their standard values before invoking a callee unless by agreement the callee expects the modified values.

There are two exceptions to the rules regarding the non-volatility of the control flags:
http://msdn.microsoft.com/en-us/library/ms235300.aspx
Post 21 Jan 2012, 02:59
View user's profile Send private message 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.