The MASM Forum Archive 2004 to 2012
Welcome, Guest. Please login or register.
August 26, 2019, 01:23:49 AM

Login with username, password and session length
Search:     Advanced search
128553 Posts in 15254 Topics by 684 Members
Latest Member: mottt
* Home Help Search Login Register
+  The MASM Forum Archive 2004 to 2012
|-+  Project Support Forums
| |-+  64 Bit Assembler
| | |-+  SIZE OF PAINTSTRUCT in x64
« previous next »
Pages: [1] Print
Author Topic: SIZE OF PAINTSTRUCT in x64  (Read 10561 times)
jorgon
Member
*****
Posts: 387



SIZE OF PAINTSTRUCT in x64
« on: October 19, 2006, 10:35:54 AM »

When running XP Professional x64 edition the system wrote an extra 4 bytes to PAINTSTRUCT than the number expected.
This happened upon WM_PAINT after the API GetOpenFileNameW returned (user having chosen a file).

I had assumed that the 64-bit version of PAINTSTRUCT was as follows:-
Code:
PAINTSTRUCT STRUCT
            DQ 0      ;+0 hDC
            DD 0      ;+8 fErase
      left  DD 0      ;+C  left   )
       top  DD 0      ;+10 top    ) RECT
     right  DD 0      ;+14 right  )
    bottom  DD 0      ;+18 bottom )
            DD 0      ;+1C fRestore
            DD 0      ;+20 fIncUpdate
            DB 32 DUP 0   ;+24 rgbReserved
ENDS
This would give a size of 68 bytes.
However the system wrote into 72 bytes.
I discovered this when I found that the next dword in data was being written over.

I just wondered if anyone else had encountered this. 
I have not yet installed Vista and I wondered if this was a querk in x64.

If an extra 4 bytes is required in this structure, I'm not too sure exactly where it is.  I am sure the RECT structure is correctly positioned at +0Ch (this tests ok in Hello64World2 which is part of GoAsm).  So it may be just before the rgbReserved field to align that field on a qword boundary, or maybe that field has been extended to 36 bytes and we haven't been told about it.
Logged

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)
Relvinian
Guest


Email
Re: SIZE OF PAINTSTRUCT in x64
« Reply #1 on: October 20, 2006, 04:32:32 AM »


I had assumed that the 64-bit version of PAINTSTRUCT was as follows:-
Code:
PAINTSTRUCT STRUCT
            DQ 0      ;+0 hDC
            DD 0      ;+8 fErase
      left  DD 0      ;+C  left   )
       top  DD 0      ;+10 top    ) RECT
     right  DD 0      ;+14 right  )
    bottom  DD 0      ;+18 bottom )
            DD 0      ;+1C fRestore
            DD 0      ;+20 fIncUpdate
            DB 32 DUP 0   ;+24 rgbReserved
ENDS


I show the following for PAINTSTRUCT from the Visual Studio 2005 .NET developer's Edition:
Code:
typedef struct tagPAINTSTRUCT {
    HDC         hdc;    ; 4-bytes in Win32  and 8-bytes in Win64
    BOOL        fErase;
    RECT        rcPaint;  ; 16-bytes in both Win32/Win64
    BOOL        fRestore;
    BOOL        fIncUpdate;
    BYTE        rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;

Size of the structure is 64-byte in length (for a Win32 system) and 68-bytes in length (for a Win64) system. But one thing you have to remember about Windows is that all their structures are divisible by 4 (for Win32) or divisible by 8 (for Win64).  So make sure you pad your structures in ASM to that amount.

The only time you don't have do to somthing like is this if the first member variable of the structure is the size of the structure.

Relvinian
Logged
P1
Global Moderator
Member
*****
Posts: 1247


Re: SIZE OF PAINTSTRUCT in x64
« Reply #2 on: October 20, 2006, 04:42:09 PM »

Align 8 in the data section would fix a move by eight problem.  Provided is a OS thing.  And is this observable with other structures?

But I read somewhere, that 64bit and/or (???) Vista would need paragraph alignment of 16 for data and code.

Regards,  P1  Cool
Logged
EduardoS
Guest


Email
Re: SIZE OF PAINTSTRUCT in x64
« Reply #3 on: October 21, 2006, 01:23:35 AM »

The calling convention in Vista says stack should always be 16 bytes aligned, for SSE code, and pointers returned by allocs are always 16 bytes aligned too... But i never heard about others...
Logged
jorgon
Member
*****
Posts: 387



Re: SIZE OF PAINTSTRUCT in x64
« Reply #4 on: October 21, 2006, 09:28:46 AM »

Thanks everyone for your answers.

Relvinian, your answer caused me to look again at the Microsoft document SWConventions.doc (my copy is 1 May 2005) which sets out the x64 spec.
You are quite right and I quote from the document:-
Quote
Structure size must be an integral multiple of its alignment, which may require padding after the last member. Since structures and unions can be grouped in arrays, each array element of a structure or union must begin and end at the proper alignment previously determined.

an example is given:-
Code:
Example 2
struct S2 { // size = 24 bytes, alignment = 8 bytes
int a;
double b;
short c;
};
which is shown graphically as having 4 bytes of padding after the dword at "a" (for correct alignment of the qword at "b") and 6 bytes of padding after the word at "c" (to bring the total size of the structure up to 24 bytes ie. divisible by 8 being the natural alignment of the whole structure).

It seems clear from what happened to me that x64 was using the padding as a expected data area, and writing to it.

I shall need to ensure that structures used in GoAsm (64-bit) are always automatically padded to the correct size.  I'll work on it.

Quote
The calling convention in Vista says stack should always be 16 bytes aligned, for SSE code

This is another thing, and when INVOKE is used, GoAsm automatically aligns the stack properly ready for the call.  This is a significant feature because it frees the assembler programmer from any concerns about stack alignment.  It means that you can call APIs from anywhere in your code without having to worry whether the call is from a "frame" or a "leaf" function.
Logged

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)
P1
Global Moderator
Member
*****
Posts: 1247


Re: SIZE OF PAINTSTRUCT in x64
« Reply #5 on: October 24, 2006, 02:58:00 PM »

which is shown graphically as having 4 bytes of padding after the dword at "a" (for correct alignment of the qword at "b") and 6 bytes of padding after the word at "c" (to bring the total size of the structure up to 24 bytes ie. divisible by 8 being the natural alignment of the whole structure).
But your problem above, does not show this behavior for structure elements, but for the structure as a whole.

Regards,  P1  Cool
Logged
jorgon
Member
*****
Posts: 387



Re: SIZE OF PAINTSTRUCT in x64
« Reply #6 on: October 24, 2006, 05:30:58 PM »

Quote
But your problem above, does not show this behavior for structure elements, but for the structure as a whole.

Yes, I know.  That's what surprised me. 
I was aware of the need to align the structure members on their natural boundary, just as you would need to do with any data in Win64.  That is achieved by aligning the structure itself (when used) to the appropriate boundary (ie. the natural boundary of the largest member), and by inserting padding in the structure itself (when declared) just before the structure member if necessary.

What I didn't expect was that the system would use any subsequent padding for its own purposes.  This means that the structure when declared must include such padding.  Otherwise the user might be tempted as I was to use the space after the structure to hold an old fashioned dword which could be overwritten by the system.

So in Win64 the MSG structure should now be 48 bytes:-
Code:
MSG      DQ 0         ;+0h hWnd
         DD 0         ;+8h message
         DD 0         ;padding for next
         DQ 0         ;+10h wParam
         DQ 0         ;+18h lParam
         DD 0         ;+20h time
         DD 0         ;+24h 1st part of point structure
         DD 0         ;+28h 2nd part of point structure
         DD 0         ;+2Ch padding to bring the overall size to 48 bytes


Logged

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)
jorgon
Member
*****
Posts: 387



Re: SIZE OF PAINTSTRUCT in x64
« Reply #7 on: January 31, 2007, 06:13:28 PM »

Quote
I shall need to ensure that structures used in GoAsm (64-bit) are always automatically padded to the correct size.  I'll work on it.

This has now been added to the very latest version of GoAsm (0.56 beta) which is now available from here.

This version:-
  • Corrects various things.
  • Allows multi-line macros to be declared using MACRO...ENDM (instead of using the continuation character which was unpopular).
  • Introduces #localdef (or LOCALEQU if you prefer), which permits you to have a definition (#define, macro or equate) which is limited in scope to its own stack frame.
  • Shows an error if you try to jump into or out of stack frames.
  • And of importance for those using GoAsm for 64-bit programming, it now (a) automatically aligns structures on the correct boundary in data at the beginning of the structure (b) automatically aligns each structure member to suit its natural boundary and (c) pads the structure at the end so that it ends on its natural boundary.

Since there was some delving into GoAsm's depths involved in the above changes, I thought it prudent to make this a beta for the moment.

Logged

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)
Pages: [1] Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP The MASM Forum Archive 2004 to 2012 | Powered by SMF 1.0.12.
© 2001-2005, Lewis Media. All Rights Reserved.
Valid XHTML 1.0! Valid CSS!