[FASM] How do structures work in locals?

Bare metal programming in PureBasic, for experienced users
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

[FASM] How do structures work in locals?

Post by Mijikai »

How do structures work in locals?

Basically i want the fasm version of this PB-Code:

Code: Select all

Structure VECTOR
  x.l
  y.l
  z.l
EndStructure

Procedure.i TestFnc(...)
  Protected *V.VECTOR
  ...
EndProcedure

Procedure.i TestFnc(...)
  Protected V.VECTOR
  ...
EndProcedure
Last edited by Mijikai on Mon Mar 12, 2018 10:40 am, edited 1 time in total.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [FASM] How do structures work in locals?

Post by Mijikai »

I mean something like this works...

Code: Select all

proc Something
locals
 X dd 0h;VECTOR
 Y dd 0h
 Z dd 0h
endl
 mov rax,addr A;<- load @Structure
 ret
endp
But thats surely not right.
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 190
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

Re: [FASM] How do structures work in locals?

Post by Tristano »

FAsm macros are documented in sec. "2.3.4 Structures" of the official documentation:

https://flatassembler.net/docs.php?article=manual#2.3.4

The structure you want to create should look something like this in FAsm:

Code: Select all

struc VECTOR x,y,z
 {
    .x dd x
    .y dd y
    .z dd z
 }
where PureBasic long variables are 4 bytes, and therefore correspond to the "dd" FAsm directive.

I'm not sure about the "locals" part ... A structure is just a means to structure data according to size — it's pattern should apply in a context-agnostic manner.
The PureBASIC Archives: FOSS Resources:
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: [FASM] How do structures work in locals?

Post by CELTIC88 »

is so easy with fasm macro look exemple

Code: Select all

IncludeFile "fasm_macro.pb"

EnableASM
DisableDebugger;very important!!!


!struct zTEst ; Structure zTEst
!First dd ?     ;First.l
!Sco dd ?       ;Sco.l
!ends         ;EndStructure

!struct sMain ;Structure sMain
!sSub zTEst ?   ;sSub.zTEst
!Par dd ?       ;Par.l
!dByte db ?     ;dByte.b
!ends         ;EndStructure

Procedure asmProc(FirstParm,Sparm.w)
  !proc asmProc FirstParm,Sparm:WORD           ;Procedure  asmProc(FirstParm,Sparm.w)
  !local stest:sMain                   ;Protected stest.sMain
  
  PUSH [FirstParm]                        
  POP [stest.sSub.First]                  ;stest\sSub\First = 1024
  MOV eax, [stest.sSub.First]             ;eax = stest\sSub\First
  
  !.if eax <> 1024                     ;if eax <> 1024  
  SUB eax,eax
  
  !.elseif eax < 1025 
  MOV eax, 2
  
  !.while eax                           ;While eax
  DEC eax             
  !.endw                                ;Wend
  
  MOV eax, [FirstParm]                  ;eax = FirstParm
  SUB ax, [Sparm]                       ;eax = eax - Sparm
  
  !.else
  MOV eax, 1
  !.endif
  
  !ret                                  ;ProcedureReturn
  !endp                               ;EndProcedure
  
  !jmp asmProc                         ;call asm func
  
EndProcedure

EnableDebugger
Debug asmProc(1024,32)
fasm_macro.pb

Code: Select all

!;\INCLUDE\MACRO\STRUCT.INC
!; Macroinstructions for defining data structures
!
!macro struct name
! { virtual at 0
!   define @struct
!   field@struct equ name
!   match child parent, name \{ restore field@struct
!			       field@struct equ child,fields@\#parent \}
!   sub@struct equ
!   struc db [val] \{ \common define field@struct .,db,<val> \}
!   struc dw [val] \{ \common define field@struct .,dw,<val> \}
!   struc du [val] \{ \common define field@struct .,du,<val> \}
!   struc dd [val] \{ \common define field@struct .,dd,<val> \}
!   struc dp [val] \{ \common define field@struct .,dp,<val> \}
!   struc dq [val] \{ \common define field@struct .,dq,<val> \}
!   struc dt [val] \{ \common define field@struct .,dt,<val> \}
!   struc rb count \{ define field@struct .,db,count dup (?) \}
!   struc rw count \{ define field@struct .,dw,count dup (?) \}
!   struc rd count \{ define field@struct .,dd,count dup (?) \}
!   struc rp count \{ define field@struct .,dp,count dup (?) \}
!   struc rq count \{ define field@struct .,dq,count dup (?) \}
!   struc rt count \{ define field@struct .,dt,count dup (?) \}
!   macro db [val] \{ \common \local anonymous
!		     define field@struct anonymous,db,<val> \}
!   macro dw [val] \{ \common \local anonymous
!		     define field@struct anonymous,dw,<val> \}
!   macro du [val] \{ \common \local anonymous
!		     define field@struct anonymous,du,<val> \}
!   macro dd [val] \{ \common \local anonymous
!		     define field@struct anonymous,dd,<val> \}
!   macro dp [val] \{ \common \local anonymous
!		     define field@struct anonymous,dp,<val> \}
!   macro dq [val] \{ \common \local anonymous
!		     define field@struct anonymous,dq,<val> \}
!   macro dt [val] \{ \common \local anonymous
!		     define field@struct anonymous,dt,<val> \}
!   macro rb count \{ \local anonymous
!		     define field@struct anonymous,db,count dup (?) \}
!   macro rw count \{ \local anonymous
!		     define field@struct anonymous,dw,count dup (?) \}
!   macro rd count \{ \local anonymous
!		     define field@struct anonymous,dd,count dup (?) \}
!   macro rp count \{ \local anonymous
!		     define field@struct anonymous,dp,count dup (?) \}
!   macro rq count \{ \local anonymous
!		     define field@struct anonymous,dq,count dup (?) \}
!   macro rt count \{ \local anonymous
!		     define field@struct anonymous,dt,count dup (?) \}
!   macro union \{ field@struct equ ,union,<
!		  sub@struct equ union \}
!   macro struct \{ field@struct equ ,substruct,<
!		  sub@struct equ substruct \} }
!
!macro ends
! { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
!			 restruc rb,rw,rd,rp,rq,rt
!			 purge db,dw,du,dd,dp,dq,dt
!			 purge rb,rw,rd,rp,rq,rt
!			 purge union,struct
!			 irpv fields,field@struct \\{ restore field@struct
!						      \\common define fields@struct fields \\}
!			 match name tail,fields@struct, \\{ if $
!							    display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
!							    err
!							    end if \\}
!			 match name=,fields,fields@struct \\{ restore @struct
!							      make@struct name,fields
!							      define fields@\\#name fields \\}
!			 end virtual \}
!   match any, sub@struct \{ tmp@struct equ field@struct
!			    restore field@struct
!			    field@struct equ tmp@struct> \}
!   restore sub@struct }
!
!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 \{ define@struct fields \} }
!
!macro define@struct name,[field,type,def]
! { common
!    virtual
!    db `name
!    load initial@struct byte from 0
!    if initial@struct = '.'
!    display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
!    err
!    end if
!    end virtual
!    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 \\\} \\} \} }
!
!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 \\} \} }
!
!enable@substruct
!
!macro define@union 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] \{ \common
!    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 \} }
!
!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 \} }
!
!;\INCLUDE\MACRO\IF.INC
!; Macroinstructions for HLL-style conditional operations
!
!macro .if [arg]
!{
!  common
!  __IF equ
!  local ..endif
!  __ENDIF equ ..endif
!  local ..else
!  __ELSE equ ..else
!  JNCOND __ELSE,arg
!}
!
!macro .else
!{
!  jmp __ENDIF
!  __ELSE:
!  restore __IF
!  __IF equ ,
!}
!
!macro .elseif [arg]
!{
!  common
!  jmp __ENDIF
!  __ELSE:
!  restore __ELSE
!  local ..else
!  __ELSE equ ..else
!  JNCOND __ELSE,arg
!}
!
!macro .endif
!{
!  if __IF eq
!   __ELSE:
!  end if
!  __ENDIF:
!  restore __ELSE
!  restore __ENDIF
!  restore __IF
!}
!
!macro .while [arg]
!{
!  common
!  local ..while
!  __WHILE equ ..while
!  local ..endw
!  __ENDW equ ..endw
!  __WHILE:
!  JNCOND __ENDW,arg
!}
!
!macro .endw
!{
!  jmp __WHILE
!  __ENDW:
!  restore __ENDW
!  restore __WHILE
!}
!
!macro .repeat
!{
!  local ..repeat
!  __REPEAT equ ..repeat
!  __REPEAT:
!}
!
!macro .until [arg]
!{
!  common
!  JNCOND __REPEAT,arg
!  restore __REPEAT
!}
!
!jnne equ je
!jnna equ ja
!jnnb equ jb
!jnng equ jg
!jnnl equ jl
!jnnae equ jae
!jnnbe equ jbe
!jnnge equ jge
!jnnle equ jle
!
!macro JNCOND label,v1,c,v2
!{
! match any,c
! \{
!   cmp v1,v2
!   jn\#c label
! \}
! match ,c
! \{
!   PARSECOND parsed@cond,v1
!   match cond,parsed@cond \\{ JNCONDEXPR label,cond \\}
! \}
!}
!
!gt equ >
!lt equ <
!
!macro PARSECOND parsed,cond
!{
! define parsed
! define neg@cond
! define status@cond
! define nest@cond
! irps symb,cond
! \{
!   define symb@cond symb
!   match >,symb
!   \\{
!      define symb@cond gt
!   \\}
!   match <,symb
!   \\{
!      define symb@cond lt
!   \\}
!   current@cond equ status@cond
!   match ,current@cond
!   \\{
!      match ~,symb
!      \\\{
!	  neg@cond equ neg@cond ~
!	  match ~~,neg@cond
!	  \\\\{
!	       define neg@cond
!	  \\\\}
!	  define symb@cond
!      \\\}
!      match (,symb
!      \\\{
!	  parsed equ parsed neg@cond,<
!	  define nest@cond +
!	  define symb@cond
!	  define neg@cond
!      \\\}
!      match any,symb@cond
!      \\\{
!	  parsed equ parsed neg@cond,symb@cond
!	  define status@cond +
!      \\\}
!   \\}
!   match status,current@cond
!   \\{
!      match &,symb
!      \\\{
!	  parsed equ parsed,&,
!	  define status@cond
!	  define symb@cond
!	  define neg@cond
!      \\\}
!      match |,symb
!      \\\{
!	  parsed equ parsed,|,
!	  define status@cond
!	  define symb@cond
!	  define neg@cond
!      \\\}
!      match (,symb
!      \\\{
!	  define nest@cond (
!      \\\}
!      match ),symb
!      \\\{
!	  match +,nest@cond
!	  \\\\{
!	       parsed equ parsed>
!	       define symb@cond
!	  \\\\}
!	  restore nest@cond
!      \\\}
!      match any,symb@cond
!      \\\{
!	  parsed equ parsed symb@cond
!      \\\}
!   \\}
! \}
!}
!
!macro define_JNCONDEXPR
!{
! macro JNCONDEXPR elabel,[mod,cond,op]
! \{
!  \common
!   \local ..t,..f
!   define t@cond ..t
!   define f@cond ..f
!  \forward
!   match ,op
!   \\{
!      match ,mod \\\{ JNCONDEL elabel,<cond> \\\}
!      match ~,mod \\\{ JCONDEL elabel,<cond> \\\}
!   \\}
!   match &:flabel:tlabel, op:f@cond:t@cond
!   \\{
!      match ,mod \\\{ JNCONDEL flabel,<cond> \\\}
!      match ~,mod \\\{ JCONDEL flabel,<cond> \\\}
!      tlabel:
!      \\local ..tnew
!      restore t@cond
!      define t@cond ..tnew
!   \\}
!   match |:flabel:tlabel, op:f@cond:t@cond
!   \\{
!      match ,mod \\\{ JCONDEL tlabel,<cond> \\\}
!      match ~,mod \\\{ JNCONDEL tlabel,<cond> \\\}
!      flabel:
!      \\local ..fnew
!      restore f@cond
!      define f@cond ..fnew
!   \\}
!  \common
!   label f@cond at elabel
!   t@cond:
!   restore t@cond
!   restore f@cond
! \}
!}
!
!macro define_JCONDEXPR
!{
! macro JCONDEXPR elabel,[mod,cond,op]
! \{
!  \common
!   \local ..t,..f
!   define t@cond ..t
!   define f@cond ..f
!  \forward
!   match ,op
!   \\{
!      match ,mod \\\{ JCONDEL elabel,<cond> \\\}
!      match ~,mod \\\{ JNCONDEL elabel,<cond> \\\}
!   \\}
!   match |:flabel:tlabel, op:f@cond:t@cond
!   \\{
!      match ,mod \\\{ JCONDEL flabel,<cond> \\\}
!      match ~,mod \\\{ JNCONDEL flabel,<cond> \\\}
!      tlabel:
!      \\local ..tnew
!      restore t@cond
!      define t@cond ..tnew
!   \\}
!   match &:flabel:tlabel, op:f@cond:t@cond
!   \\{
!      match ,mod \\\{ JNCONDEL tlabel,<cond> \\\}
!      match ~,mod \\\{ JCONDEL tlabel,<cond> \\\}
!      flabel:
!      \\local ..fnew
!      restore f@cond
!      define f@cond ..fnew
!   \\}
!  \common
!   label f@cond at elabel
!   t@cond:
!   restore t@cond
!   restore f@cond
! \}
!}
!
!macro define_JNCONDEL
!{
! macro JNCONDEL label,cond
! \{
!   \local COND
!   match car=,cdr,:cond
!   \\{
!      define_JNCONDEXPR
!      define_JCONDEXPR
!      define_JCONDEL
!      define_JNCONDEL
!      JNCONDEXPR label,cond
!      purge JNCONDEXPR,JCONDEXPR,JCONDEL,JNCONDEL
!      define COND
!   \\}
!   match c,cond ; replace gt and lt
!   \\{
!      match =COND =signed v1>==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jl label
!	  define COND
!      \\\}
!      match =COND =signed v1<==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jg label
!	  define COND
!      \\\}
!      match =COND v1>==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jb label
!	  define COND
!      \\\}
!      match =COND v1<==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  ja label
!	  define COND
!      \\\}
!      match =COND v1==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jne label
!	  define COND
!      \\\}
!      match =COND v1<>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  je label
!	  define COND
!      \\\}
!      match =COND =signed v1>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jle label
!	  define COND
!      \\\}
!      match =COND =signed v1<v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jge label
!	  define COND
!      \\\}
!      match =COND v1>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jbe label
!	  define COND
!      \\\}
!      match =COND v1<v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jae label
!	  define COND
!      \\\}
!      match =COND =ZERO?, COND c
!      \\\{
!	  jnz label
!	  define COND
!      \\\}
!      match =COND =CARRY?, COND c
!      \\\{
!	  jnc label
!	  define COND
!      \\\}
!      match =COND =OVERFLOW?, COND c
!      \\\{
!	  jno label
!	  define COND
!      \\\}
!      match =COND =SIGN?, COND c
!      \\\{
!	  jns label
!	  define COND
!      \\\}
!      match =COND =PARITY?, COND c
!      \\\{
!	  jnp label
!	  define COND
!      \\\}
!      match =COND v, COND c
!      \\\{
!	  if v eqtype 0
!	   if ~ v
!	    jmp label
!	   end if
!	  else if v eqtype eax
!	   test v,v
!	   jz label
!	  else
!	   cmp v,0
!	   je label
!	  end if
!      \\\}
!   \\}
! \}
!}
!
!macro define_JCONDEL
!{
! macro JCONDEL label,cond
! \{
!   \local COND
!   match car=,cdr,:cond
!   \\{
!      define_JNCONDEXPR
!      define_JCONDEXPR
!      define_JCONDEL
!      define_JNCONDEL
!      JCONDEXPR label,cond
!      purge JNCONDEXPR,JCONDEXPR,JCONDEL,JNCONDEL
!      define COND
!   \\}
!   match c,cond ; replace gt and lt
!   \\{
!      match =COND =signed v1>==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jge label
!	  define COND
!      \\\}
!      match =COND =signed v1<==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jle label
!	  define COND
!      \\\}
!      match =COND v1>==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jae label
!	  define COND
!      \\\}
!      match =COND v1<==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jbe label
!	  define COND
!      \\\}
!      match =COND v1==v2, COND c
!      \\\{
!	  cmp v1,v2
!	  je label
!	  define COND
!      \\\}
!      match =COND v1<>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jne label
!	  define COND
!      \\\}
!      match =COND =signed v1>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jg label
!	  define COND
!      \\\}
!      match =COND =signed v1<v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jl label
!	  define COND
!      \\\}
!      match =COND v1>v2, COND c
!      \\\{
!	  cmp v1,v2
!	  ja label
!	  define COND
!      \\\}
!      match =COND v1<v2, COND c
!      \\\{
!	  cmp v1,v2
!	  jb label
!	  define COND
!      \\\}
!      match =COND =ZERO?, COND c
!      \\\{
!	  jz label
!	  define COND
!      \\\}
!      match =COND =CARRY?, COND c
!      \\\{
!	  jc label
!	  define COND
!      \\\}
!      match =COND =OVERFLOW?, COND c
!      \\\{
!	  jo label
!	  define COND
!      \\\}
!      match =COND =SIGN?, COND c
!      \\\{
!	  js label
!	  define COND
!      \\\}
!      match =COND =PARITY?, COND c
!      \\\{
!	  jp label
!	  define COND
!      \\\}
!      match =COND v, COND c
!      \\\{
!	  if v eqtype 0
!	   if v
!	    jmp label
!	   end if
!	  else if v eqtype eax
!	   test v,v
!	   jnz label
!	  else
!	   cmp v,0
!	   jne label
!	  end if
!      \\\}
!   \\}
! \}
!}
!
!define_JNCONDEXPR
!define_JCONDEXPR
!define_JNCONDEL
!define_JCONDEL
!
!;\INCLUDE\MACRO\PROC32.INC
!; Macroinstructions for defining and calling procedures
!
!macro stdcall proc,[arg]		; directly call STDCALL procedure
! { common
!    if ~ arg eq
!   reverse
!    pushd arg
!   common
!    end if
!    call proc }
!
!macro invoke proc,[arg] 		; indirectly call STDCALL procedure
! { common
!    if ~ arg eq
!   reverse
!     pushd arg
!   common
!    end if
!    call [proc] }
!
!macro ccall proc,[arg]			; directly call CDECL procedure
! { common
!    size@ccall = 0
!    if ~ arg eq
!   reverse
!    pushd arg
!    size@ccall = size@ccall+4
!   common
!    end if
!    call proc
!    if size@ccall
!    add esp,size@ccall
!    end if }
!
!macro cinvoke proc,[arg]		; indirectly call CDECL procedure
! { common
!    size@ccall = 0
!    if ~ arg eq
!   reverse
!    pushd arg
!    size@ccall = size@ccall+4
!   common
!    end if
!    call [proc]
!    if size@ccall
!    add esp,size@ccall
!    end if }
!
!macro proc [args]			; define procedure
! { common
!    match name params, args>
!    \{ define@proc name,<params \} }
!
!prologue@proc equ prologuedef
!
!macro prologuedef procname,flag,parmbytes,localbytes,reglist
! { local loc
!   loc = (localbytes+3) and (not 3)
!   parmbase@proc equ ebp+8
!   localbase@proc equ ebp-loc
!   if parmbytes | localbytes
!    push ebp
!    mov ebp,esp
!    if localbytes
!     sub esp,loc
!    end if
!   end if
!   irps reg, reglist \{ push reg \} }
!
!epilogue@proc equ epiloguedef
!
!macro epiloguedef procname,flag,parmbytes,localbytes,reglist
! { irps reg, reglist \{ reverse pop reg \}
!   if parmbytes | localbytes
!    leave
!   end if
!   if flag and 10000b
!    retn
!   else
!    retn parmbytes
!   end if }
!
!close@proc equ
!
!macro define@proc name,statement
! { local params,flag,regs,parmbytes,localbytes,current
!   if used name
!   name:
!   match =stdcall args, statement \{ params equ args
!				     flag = 11b \}
!   match =stdcall, statement \{ params equ
!				flag = 11b \}
!   match =c args, statement \{ params equ args
!			       flag = 10001b \}
!   match =c, statement \{ params equ
!			  flag = 10001b \}
!   match =params, params \{ params equ statement
!			    flag = 0 \}
!   match =uses reglist=,args, params \{ regs equ reglist
!					params equ args \}
!   match =regs =uses reglist, regs params \{ regs equ reglist
!					     params equ \}
!   match =regs, regs \{ regs equ \}
!   match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
!   virtual at parmbase@proc
!   match =,args, params \{ defargs@proc args \}
!   match =args@proc args, args@proc params \{ defargs@proc args \}
!   parmbytes = $-(parmbase@proc)
!   end virtual
!   name # % = parmbytes/4
!   all@vars equ
!   current = 0
!   macro locals
!   \{ virtual at localbase@proc+current
!      macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
!      struc db [val] \\{ \common deflocal@proc .,db,val \\}
!      struc du [val] \\{ \common deflocal@proc .,du,val \\}
!      struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
!      struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
!      struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
!      struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
!      struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
!      struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
!      struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
!      struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
!      struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
!      struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
!      struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
!   macro endl
!   \{ purge label
!      restruc db,du,dw,dp,dd,dt,dq
!      restruc rb,rw,rp,rd,rt,rq
!      current = $-(localbase@proc)
!      end virtual \}
!   macro ret operand
!   \{ match any, operand \\{ retn operand \\}
!      match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
!   macro finish@proc
!   \{ localbytes = current
!      match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
!      end if \} }
!
!macro defargs@proc [arg]
! { common
!    if ~ arg eq
!   forward
!     local ..arg,current@arg
!     match argname:type, arg
!      \{ current@arg equ argname
!	 label ..arg type
!	 argname equ ..arg
!	 if qqword eq type
!	   dd ?,?,?,?,?,?,?,?
!	 else if dqword eq type
!	   dd ?,?,?,?
!	 else if tbyte eq type
!	   dd ?,?,?
!	 else if qword eq type | pword eq type
!	   dd ?,?
!	 else
!	   dd ?
!	 end if \}
!     match =current@arg,current@arg
!      \{ current@arg equ arg
!	 arg equ ..arg
!	 ..arg dd ? \}
!   common
!     args@proc equ current@arg
!   forward
!     restore current@arg
!   common
!    end if }
!
!macro deflocal@proc name,def,[val] { name def val }
!
!macro deflocal@proc name,def,[val]
! { common
!    match vars, all@vars \{ all@vars equ all@vars, \}
!    all@vars equ all@vars name
!   forward
!    local ..var,..tmp
!    ..var def val
!    match =?, val \{ ..tmp equ \}
!    match any =?, val \{ ..tmp equ \}
!    match any (=?), val \{ ..tmp equ \}
!    match =label, def \{ ..tmp equ \}
!    match tmp : value, ..tmp : val
!     \{ tmp: end virtual
!	initlocal@proc ..var,def value
!	virtual at tmp\}
!   common
!    match first rest, ..var, \{ name equ first \} }
!
!struc label type { label . type }
!
!macro initlocal@proc name,def
! { virtual at name
!    def
!    size@initlocal = $ - name
!   end virtual
!   position@initlocal = 0
!   while size@initlocal > position@initlocal
!    virtual at name
!     def
!     if size@initlocal - position@initlocal < 2
!      current@initlocal = 1
!      load byte@initlocal byte from name+position@initlocal
!     else if size@initlocal - position@initlocal < 4
!      current@initlocal = 2
!      load word@initlocal word from name+position@initlocal
!     else
!      current@initlocal = 4
!      load dword@initlocal dword from name+position@initlocal
!     end if
!    end virtual
!    if current@initlocal = 1
!     mov byte [name+position@initlocal],byte@initlocal
!    else if current@initlocal = 2
!     mov word [name+position@initlocal],word@initlocal
!    else
!     mov dword [name+position@initlocal],dword@initlocal
!    end if
!    position@initlocal = position@initlocal + current@initlocal
!   end while }
!
!macro endp
! { purge ret,locals,endl
!   finish@proc
!   purge finish@proc
!   restore regs@proc
!   match all,args@proc \{ restore all \}
!   restore args@proc
!   match all,all@vars \{ restore all \} }
!
!macro local [var]
! { common
!    locals
!   forward done@local equ
!    match varname[count]:vartype, var
!    \{ match =BYTE, vartype \\{ varname rb count
!				restore done@local \\}
!       match =WORD, vartype \\{ varname rw count
!				restore done@local \\}
!       match =DWORD, vartype \\{ varname rd count
!				 restore done@local \\}
!       match =PWORD, vartype \\{ varname rp count
!				 restore done@local \\}
!       match =QWORD, vartype \\{ varname rq count
!				 restore done@local \\}
!       match =TBYTE, vartype \\{ varname rt count
!				 restore done@local \\}
!       match =DQWORD, vartype \\{ label varname dqword
!				  rq count*2
!				  restore done@local \\}
!       match =QQWORD, vartype \\{ label varname qqword
!				  rq count*4
!				  restore done@local \\}
!       match =XWORD, vartype \\{ label varname xword
!				 rq count*2
!				 restore done@local \\}
!       match =YWORD, vartype \\{ label varname yword
!				 rq count*4
!				 restore done@local \\}
!       match , done@local \\{ virtual
!			       varname vartype
!			      end virtual
!			      rb count*sizeof.\#vartype
!			      restore done@local \\} \}
!    match :varname:vartype, done@local:var
!    \{ match =BYTE, vartype \\{ varname db ?
!				restore done@local \\}
!       match =WORD, vartype \\{ varname dw ?
!				restore done@local \\}
!       match =DWORD, vartype \\{ varname dd ?
!				 restore done@local \\}
!       match =PWORD, vartype \\{ varname dp ?
!				 restore done@local \\}
!       match =QWORD, vartype \\{ varname dq ?
!				 restore done@local \\}
!       match =TBYTE, vartype \\{ varname dt ?
!				 restore done@local \\}
!       match =DQWORD, vartype \\{ label varname dqword
!				  dq ?,?
!				  restore done@local \\}
!       match =QQWORD, vartype \\{ label varname qqword
!				  dq ?,?,?,?
!				  restore done@local \\}
!       match =XWORD, vartype \\{ label varname xword
!				 dq ?,?
!				 restore done@local \\}
!       match =YWORD, vartype \\{ label varname yword
!				 dq ?,?,?,?
!				 restore done@local \\}
!       match , done@local \\{ varname vartype
!			      restore done@local \\} \}
!    match ,done@local
!    \{ var
!       restore done@local \}
!   common
!    endl }
interested in Cybersecurity..
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [FASM] How do structures work in locals?

Post by Mijikai »

Thanks for the answers especially Celtic88 very helpful :)
Post Reply