News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Compile time structure size checking and alignment.

Started by Relvinian, November 14, 2006, 09:44:29 AM

Previous topic - Next topic

Relvinian

Hey all,

I am unable to find much helpful information on how to achieve the following two questions...Any help, places to read, etc will be greatly appreciated. Both of the questions are based on MASM (which is what I need the most). If you have related information for GoAsm, let me know also.   :toothy

1) If I declare a structure of something, how to I go about checking the size to make sure it is divisible by a # and echo to the screen if it isn't during compile time?

2) When using MASM to compile structures, you can use the default by not specifying /Zp...But if I use /Zp8 and I have one or more structure in the *same* file that must be /Zp1 (like reading disk data, etc), how do I change the compiling alignment in the source file for a particular structure and then set it back to the default?

Thanks

Relvinian

ToutEnMasm


Align in the source code is valid only for the next definition following it.
I hope only that masm return to the defaut alignment after that (/ZpN).
                          ToutEnMasm
                               

Ratch

Relvinian,

QuoteI am unable to find much helpful information on how to achieve the following two questions...Any help, places to read, etc will be greatly appreciated. Both of the questions are based on MASM (which is what I need the most). If you have related information for GoAsm, let me know also.

     You need to become more familiar with Google.  http://doc.ddart.net/asm/Microsoft_MASM_Programmers_Guide_v6.1/Chap_05.htm

QuoteAlignment Value and Offsets for Structures

Data access to structures is faster on aligned fields than on unaligned fields. Therefore, alignment gains speed at the cost of space. Alignment improves access on 16-bit and 32-bit processors but makes no difference in programs executing on an 8-bit 8088 processor.

The way the assembler aligns structure fields determines the amount of space required to store a variable of that type. Each field in a structure has an offset relative to 0. If you specify an alignment in the structure declaration (or with the /Zpn command-line option), the offset for each field may be modified by the alignment (or n).


The only values accepted for alignment are 1, 2, and 4. The default is 1. If the type declaration includes an alignment, each field is aligned to either the field's size or the alignment value, whichever is less. If the field size in bytes is greater than the alignment value, the field is padded so that its offset is evenly divisible by the alignment value. Otherwise, the field is padded so that its offset is evenly divisible by the field size.


Any padding required to reach the correct offset for the field is added prior to allocating the field. The padding consists of zeros and always precedes the aligned field. The size of the structure must also be evenly divisible by the structure alignment value, so zeros may be added at the end of the structure.


If neither the alignment nor the /Zp command-line option is used, the offset is incremented by the size of each data directive. This is the same as a default alignment equal to 1. The alignment specified in the type declaration overrides the /Zp command-line option.


These examples show how the assembler determines offsets:

STUDENT2    STRUCT  2   ; Alignment value is 2
  score     WORD    1   ; Offset = 0
  id        BYTE    2   ; Offset = 2 (1 byte padding added)
  year      DWORD   3   ; Offset = 4
  sname     BYTE    4   ; Offset = 8 (1 byte padding added)
STUDENT2    ENDS




One byte of padding is added at the end of the first byte-sized field. Otherwise, the offset of the year field would be 3, which is not divisible by the alignment value of 2. The size of this structure is now 9 bytes. Since 9 is not evenly divisible by 2, 1 byte of padding is added at the end of student2.

STUDENT4    STRUCT  4            ; Alignment value is 4
  sname     BYTE    1            ; Offset =  0 (1 byte padding added)
  score     WORD    10 DUP (100) ; Offset =  2
  year      BYTE    2            ; Offset = 22 (1 byte padding
                                 ;   added so offset of next field
                                 ;   is divisible by 4)
  id        DWORD   3            ; Offset = 24
STUDENT4    ENDS


QuoteIf you have related information for GoAsm, let me know also. 

     I stopped using GoAsm when it stopped being free.  If I am wrong about this, let me know.

Quote2) When using MASM to compile structures, you can use the default by not specifying /Zp...But if I use /Zp8 and I have one or more structure in the *same* file that must be /Zp1 (like reading disk data, etc), how do I change the compiling alignment in the source file for a particular structure and then set it back to the default?

     Notice that Zp8 is invalid according to the documentation.  Make two different files for the two types of structures, MASM them separately, and link 'em together.  Ratch




Tedd

1)

    IF (SIZEOF some_struct MOD 8)
        .ERR <Bad structure size.. blah blah..>
    ENDIF


2) Place "ALIGN 8" before anything you want to align -- it will insert the necessary padding to align it at that point, anything after that point is generated as normal (i.e. no extra attemtp is made to align, unless you specifically use another ALIGN.)
Aligning to 1 is pointless. That would mean align to a byte - you can't help but be aligned to bytes! However, inserting "ALIGN 1" should stop the alignment at that specific point (if it would otherwise be generated) with any other alignments being automatically generated as normal afterwards.
No snowflake in an avalanche feels responsible.

bushpilot

QuoteI stopped using GoAsm when it stopped being free.  If I am wrong about this, let me know.

GoAsm is free.

Greg

ToutEnMasm


And what happend after a directive align 8 in the source with ml /Zp4 (for example) ?.
Did masm return to an alignement of 4 by defaut?.
I think he return but i am not sure
                       ToutEnMasm
                                       

Relvinian

Ratch,

Thanks for the link to the MASM documentation. That information is VERY helpful.  Thanks again.

As per /Zp8 or /Zp16 alignment values, the documentation may not have them included, but ML.EXE (v6.15.8803) does support them. You can see this by doing something like the follow:

WNDCLASSEX STRUCT OS_STRUCT_ALIGNMENT
  cbSize            DWORD ? ; must be set to the size of WNDCLASSEX
  style             DWORD ? ; class styles to use.
  lpfnWndProc       DWORD ? ; window procedure called to process messages
  cbClsExtra        DWORD ? ; extra data for this class
  cbWndExtra        DWORD ? ; extra data for each window creating on this class
  hInstance         DWORD ? ; process or dll instance where class is instaniated
  hIcon             DWORD ? ; default icon to use for windows
  hCursor           DWORD ? ; default cursor to use for windows
  hbrBackground     DWORD ? ; default color to set the background
  lpszMenuName      DWORD ? ; default menu associated with window
  lpszClassName     DWORD ? ; name of the class (custom or OS specific)
  hIconSm           DWORD ? ; small icon to display in the window
WNDCLASSEX ENDS


If you get forget to define the OS_STRUCT_ALIGNMENT value when compiling, ML will report:

\asm\includes\User32.inc(905) : error A2006: undefined symbol : OS_STRUCT_ALIGNMENT
\asm\includes\User32.inc(905) : error A2064: structure alignment must be 1, 2, 4, 8, or 16



Tedd,
Thank you for help with compile time checking of values. This information will help me greatly.

   IF (SIZEOF OE_IDX_RECORD MOD 4)
      .ERR <Structure alignment is invalid>
   ENDIF




Relvinian

PS - Now, if I can mimic this behavior in GoASM, I'd be a happy camper.  :dance:

Ratch

Relvinian,

     Damn! Old documentation.  Sorry about that.  Anyway I am happy you found it link helpful.  By the way, I thought the second example was in error.  RWA

Ratch

bushpilot,

QuoteGoAsm is free.

     Sorry, I meant GoBug.  I just rebooted my brain. Ratch