flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > fasm1:struct macro additions & bugfixies

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 18 Feb 2019, 14:00
Code:
def.rb equ db ; this could be placed out of struct.inc file
def.rw equ dw
def.rd equ dd
def.rp equ dp
def.rq equ dq
def.rt equ dt
datadef@directives equ db,dw,du,dd,dp,dq,dt
datarsv@directives equ rb,rw,rd,rp,rq,rt    

Code:
macro struct@overridedefs [datadef] {
        struc datadef [val:?] \{ \common define field@struct .,datadef,<val> \}
        macro datadef [val:?] \{ \common
                \local anonimous
                define field@struct anonimous,datadef,<val> \} }
macro struct@overridersvs [datadef] {
        struc datadef count \{ \common define field@struct .,def.#datadef,count dup (?) \}
        macro datadef count \{ \common
                \local anonimous
                define field@struct anonimous,def.datadef,count dup (?) \} }
macro struct@restoredefs [datadef] {
        restruc datadef
        purge datadef }    

Code:
macro struct names {
        match name tail, names: \{
                virtual
                        db \`name
                        load initial@struct byte from $$
                        if initial@struct = '.'
                                display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
                                err
                        end if
                end virtual

                macro ends \\{
                        match , sub@struct \\\{
                                if $
                                        display 'Error: definition of ',\`name,' contains illegal instructions.',0Dh,0Ah
                                        err
                                end if

                                match any,datadef@directives \\\\{ struct@restoredefs any \\\\}
                                match any,datarsv@directives \\\\{ struct@restoredefs any \\\\}

                                purge union,struct,ends

                                irpv fields,field@struct \\\\{
                                        restore field@struct
                                 \\\\common
                                        restore @struct
                                        make@struct name,fields
                                        define fields@\#name fields \\\\}
                                end virtual \\\} ;end virtual must be after make@struct
                        match any, sub@struct \\\{
                                tmp@struct equ field@struct
                                restore field@struct
                                field@struct equ tmp@struct> \\\}
                        restore sub@struct \\}

                ;match :,tail \\{ \\}
                match parent:,tail \\{ field@struct equ fields@\\#parent \\} \}

        match any,datadef@directives \{ struct@overridedefs any \}
        match any,datarsv@directives \{ struct@overridersvs any \}
        irp datadef,union,struct \{
                macro datadef \\{
                        field@struct equ ,sub\#datadef,<
                        sub@struct equ sub\#datadef \\} \}

        define @struct
        sub@struct equ
        virtual at 0 }    

Code:
macro union names { ; not finished - original make@union should be renamed to make@subunion and make@union will be hybrid of make@subunion and make@struct
        struct names
        define @union }    

Code:
macro make@struct name,[field,type,def] {
 common
        local define
        define equ name
 forward
        local sub
        match , field \{
                make@substruct type,name,sub def
                define equ define,.,sub, \}
        match any, field \{ define equ define,.#field,type,<def> \}
 common
        match fields, define \{
                match no, @union \\{ define@struct fields \\}
                match , @union \\{
                        restore @union
                        define@union fields \\} \} }    

Code:
macro define@union name,[field,type,def] {
 forward
        if ~ field eq .
                virtual at 0
                        name#field type def
                        sizeof.#name#field = $ - name#field
                end virtual
                if sizeof.#name#field > $
                        rb sizeof.#name#field - $
                end if
        else
                virtual at 0
                        label name#.#type
                        rb sizeof.#type
                end virtual
                if sizeof.#type > $
                        rb sizeof.#type - $
                end if
        end if
 common
        sizeof.#name = $
        restruc name
        struc name value \{
                \local \..base
                match , @struct \\{ define field@struct .,name,<value> \\}
                match no, @struct \\{
                        label \..base
                        last@union equ
 forward
                        match any, last@union \\\{
                        virtual at \..base
                                field type def
                        end virtual \\\}
                        match , last@union \\\{
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{ field type value \\\\} \\\}
                        last@union equ field
 common
                        if sizeof.#name > $ - \..base
                                rb sizeof.#name - ($ - \..base)
                        end if
                        label . at \..base \\}
        \}
        macro name value \{
                \local anonymous
                match , @struct \\{ define field@struct anonymous,name,<value> \\}
                match no, @struct \\{ ..anonymous name value \\} \} } ;value or <value>    

Code:
macro define@struct name,[field,type,def] {
 common
        local list
        list equ
 forward
        if ~ field eq .
                name#field type def
                sizeof.#name#field = $ - name#field
        else
                label name#.#type
                rb sizeof.#type
        end if
        local value
        match any, list \{ list equ list, \}
        list equ list <value>
 common
        sizeof.#name = $
        restruc name
        match values, list \{
                struc name value \\{
                        \\local \\..base
                        match , @struct \\\{ define field@struct .,name,<values> \\\}
                        match no, @struct \\\{
                                label \\..base
 forward
                                match , value \\\\{ field type def \\\\}
                                match any, value \\\\{
                                        field type value
                                        if ~ field eq .
                                                rb sizeof.#name#field - ($-field)
                                        end if \\\\}
 common
                                label . at \\..base \\\}
                \\}
                macro name value \\{
                        match , @struct \\\{
                                \\\local anonymous
                                define field@struct anonymous,name,<values> \\\}
                        match no, @struct \\\{
 forward
                                match , value \\\\{ type def \\\\}
                                match any, value \\\\{
                                        \\\\local ..field
                                        ..field = $
                                        type value
                                        if ~ field eq .
                                                rb sizeof.#name#field - ($-..field)
                                        end if \\\\}
 common
                        \\\} \\} \} }    

Code:
macro enable@substruct {
        macro make@substruct substruct,parent,name,[field,type,def] \{
         \common
                \local define
                define equ parent,name
         \forward
                \local sub
                match , field \\{
                        match any, type \\\{
                                enable@substruct
                                make@substruct type,parent,sub def
                                purge make@substruct
                                define equ define,.,sub, \\\} \\}
                match any, field \\{ define equ define,.\#field,type,<def> \\}
         \common
                match fields, define \\{ define@\#substruct fields \\} \} }    

Code:
enable@substruct    

Code:
macro define@subunion parent,name,[field,type,def] {
 common
        virtual at parent#.#name
 forward
                if ~ field eq .
                        virtual at parent#.#name
                                parent#field type def
                                sizeof.#parent#field = $ - parent#field
                        end virtual
                        if sizeof.#parent#field > $ - parent#.#name
                                rb sizeof.#parent#field - ($ - parent#.#name)
                        end if
                else
                        virtual at parent#.#name
                                label parent#.#type
                                type def
                        end virtual
                        label name#.#type at parent#.#name
                        if sizeof.#type > $ - parent#.#name
                                rb sizeof.#type - ($ - parent#.#name)
                        end if
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
                last@union equ
 forward
                match any, last@union \\{
                        virtual at .\#name
                                field type def
                        end virtual \\}
                match , last@union \\{
                        match , value \\\{ field type def \\\}
                        match any, value \\\{ field type value \\\} \\}
                last@union equ field
 common
                rb sizeof.#name - ($ - .\#name) \}
        macro name value \{
         \common
                \local ..anonymous
                ..anonymous name value \} }    

Code:
macro define@substruct parent,name,[field,type,def] {
 common
        virtual at parent#.#name
 forward
                local value
                if ~ field eq .
                        parent#field type def
                        sizeof.#parent#field = $ - parent#field
                else
                        label parent#.#type
                        rb sizeof.#type
                end if
 common
                sizeof.#name = $ - parent#.#name
        end virtual
        struc name value \{
                label .\#name
 forward
                match , value \\{ field type def \\}
                match any, value \\{
                        field type value
                        if ~ field eq .
                                rb sizeof.#parent#field - ($-field)
                        end if \\}
 common
        \}
        macro name value \{
                \local ..anonymous
                ..anonymous name \} }    

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 19 Feb 2019, 08:39; edited 6 times in total
Post 18 Feb 2019, 14:00
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 18 Feb 2019, 21:07
List of + additions and - bugfixies from original struct macro:
+ Top level union definition
+ struct is architecture independent now
- subunions now accept only 1 argument the only that stored in subunion
(what additions are missed: 1) support of empty body for struct-ends & union-ends blocks - may be it havn`t practical case; 2) support of alignment & natural alignment of fields (MS structs almost all); 3) support of prestruct forced alignment (some structs that expect VEX processing instructions over them); 4) support of padding; 5) arrays; 6) sequences with varsize elements - may be 5 & 6 unrealizable in common case)
bug remain unfixed: parameters that goes to struct are cover all struct fields even unnamed ones (examples of structs (included with fasm) - builded in special form to avoid that weakness)

globalsymbols used for struct processing:
datadef@directives - architecture dependant list of data definition directives
datarsv@directives - architecture dependant list of data reservation directives
@struct - marker that we are in struct when it empty
@union - marker that we are in struct (top level union) when it empty
sub@struct - marker holding type of substruct that we are in or empty otherwise
last@union - used only within define@union & define@subunion macros outer of them holds garbage

main macros for struct processing:
struct - for struct definition
union - for union definition
ends - encapsulated in struct - finalize struct|union and their subs definitions

helper macros for struct processing:
struct@overridedefs, struct@overridersvs, struct@restoredefs - for overriding & restoring action of data definition & reserving directives

make@struct - determine type of define@ prefixed macro and needance of substructure processing for every field
enable@substruct(and make@substruct in it) - for substructure processing

define@ prefixed macros - defines same name struc & macro for union or struct accordingly to postfix (same for subs).

2 more globalsymbols I missed:
field@struct - if some macro expects to be processed within struct-ends or union-ends block it should define that symbol, outer of such blocks that symbol holds garbage

fields@... (instead of ... the name of structure) - used internaly in struct-ends or union-ends block, outer of that blocks remain hold a value with list of field-type-def sequences for that structure

now I can back to https://board.flatassembler.net/topic.php?t=20945 with clear Совѣсть.


Last edited by ProMiNick on 19 Feb 2019, 09:47; edited 2 times in total
Post 18 Feb 2019, 21:07
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 19 Feb 2019, 09:06
Tomasz, I`m not sure only in one place - last row of macro define@union:
Code:
match no, @struct \\{ ..anonymous name value \\} \} } ;value or <value>    

should value be enclosed in <> or <> could be omitted?
Post 19 Feb 2019, 09:06
View user's profile Send private message Send e-mail 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.