EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

member.htm
Class
MEMBER
Encodings
MemberEnc
Procedures
MemberAdd
MemberCreate
MemberUpdate

Class MEMBER describers a named structure member. When a STRUC is defined, each its D* statement with a label creates MEMBER record added to its Sss.MemberBuffer. Local member names are similary kept in Sss.PgmPool until end of program.
Structure members themselves create a plain-numeric symbols. Address symbols will be created from them whenever the structure is expanded (data variable created with DS).
Declaring a STRUC/ENDSTRUC block creates symbol from each its member, no matter if the structure will be ever expanded in data section or not. Name of such symbols is created from structure name appended with local member name. Their type is 'N'.
When the structure is expanded (using DS statement), another set of symbols is created, their name is constructed from DS label appended with local member name.


Example
Inner STRUC ; Structure Inner is added on Pgm.SssList. D W ; Unnamed data do not create structure member nor a symbol. .Inn1 D W ; Member .Inn1 is added to Sss.MemberBuffer. Symbol Inner.Inn1 is created. ENDSTRUC Inner Outer STRUC ; Struc Outer is added on Pgm.SssList. .Out1 D W ; Member .Out1 is added to Sss.MemberBuffer. Symbol Outer.Out1 is created. .Out2 D Inner ; Members .Out2, .Out2.Inn1 are added to Sss.MemberBuffer. Symbol Outer.Out2 is created. ENDSTRUC Outer Var D Outer ; Definition of structured memory variable. ; This creates symbols Var, Var.Out1, Var.Out2, Var.Out2.Inn1.
member PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32
 INCLUDEHEAD "euroasm.htm" ; Interface (structures, symbols and macros) of other modules.
 sss HEAD  ; Start of module interface.
↑ MEMBER
represents one member of a structure or library.
MEMBER   STRUC ; Description of named data (D* statements) inside the structure.
.NamePtr   D D ; Pointer to local member name.
.NameSize  D D ; Number of bytes in member name.
.Offset    D D ; Aligned offset of this member relative to start of the structure.
.Size      D D ; Size of member value in bytes.
.Status    D D ; DataType in LSB ('B','U','W','D','Q','T')
            ENDSTRUC MEMBER
↑ MemberEnc
Encoding of flags used in MEMBER.Status.
memberType EQU 0x0000_00FF ; DataType od structure member ('B','U','W','D','Q','T').

  ENDHEAD sss ; End of module interface.
↑ MemberAdd SssPtr, StmPtr, DstrucPtr
MemberAdd is called when D* data are defined inside STRUC/ENDSTRUC block.
It creates a new MEMBER record in Sss.MemberBuffer from D* statement, which is parsed and executed in Stm.
When Stm contains DS statement (structured data variable defined inside outer structure), all members from inner structure are concatenated with Stm local label and added on Sss.MemberBuffer, too.
Input
SssPtr ^SSS structure which to add the member to.
StmPtr Parsed D* STM with member information.
DstrucPtr ^SSS (inner) structure of DS data, otherwise 0.
Output
-
Error
-
Example
Inner STRUC .Inn1 DD D ; MemberAdd called here creates member .Inn1 of Inner structure. ENDSTRUC Inner Outer STRUC .Out1 DD D ; MemberAdd called here creates member .Out1 of Outer structure. .Out2 DS Inner ; MemberAdd called here creates members .Out2 and .Out2.Inn1 of Outer structure. ENDSTRUC Outer Var DS Outer ; Definition of structured memory variable.
See also
MemberCreate. MemberUpdate.
Invokes
EaBufferRelease EaBufferReserve
Invoked by
PseudoData
MemberAdd Procedure SssPtr, StmPtr, DstrucPtr
OutMember  LocalVar Size=SIZE#MEMBER
InnMember  LocalVar Size=SIZE#MEMBER
      MOV EBX,[%StmPtr]
      MOV EDI,[%SssPtr]
      MOV ESI,[EBX+STM.LabelPtr]
      MOV ECX,[EBX+STM.LabelSize]
      PoolStore [EDI+SSS.PgmPool],ESI,ECX
      LEA EDI,[%OutMember]
      MOV [EDI+MEMBER.NamePtr],EAX
      MOV [EDI+MEMBER.NameSize],ECX
      MOV EAX,[EBX+STM.Status]
      MOV EDX,[EBX+STM.Size]
      MOV [EDI+MEMBER.Status],EAX
      MOV [EDI+MEMBER.Size],EDX
      MOV ESI,[%SssPtr]
      MOV EAX,[ESI+SSS.OrgLow]
      ADD EAX,[EBX+STM.AlignBytes]
      MOV [EDI+MEMBER.Offset],EAX
      BufferStore [ESI+SSS.MemberBuffer],EDI,SIZE#MEMBER
      Msg cc=C,'9314',MemberAdd
     ; If the added member (.Out2) is structured, its submembers will be stored, too.
      MOV EDX,[%DstrucPtr]
      TEST EDX
      JZ .90:
      JNSt [EDX+SSS.Status],sssStructure,.90:
      MOV EBX,ESI
 ; EDI=^MEMBER just added (".Out2").
 ; EBX=^SSS struc which the member was just added to (Outer)
 ; EDX=^SSS belonging to the added member (Inner).
 ; Local name of each member from structure EDX (".Inn1") will be prefixed with 
 ; member name (".Out2"), saved on [EBX+SSS.PgmPool] and added to [EBX+SSS.MemberBuffer].
      BufferRetrieve [EDX+SSS.MemberBuffer]
      TEST ECX
      JZ .90:
 .20: PUSH ECX ; ESI=^MEMBER from inner structure (.Inn1)
        LEA EDX,[%InnMember]
        MOV EAX,[ESI+MEMBER.Status]
        MOV ECX,[ESI+MEMBER.Size]
        MOV [EDX+MEMBER.Status],EAX
        MOV [EDX+MEMBER.Size],ECX
        MOV EAX,[EDI+MEMBER.Offset]
        ADD EAX,[ESI+MEMBER.Offset]
        MOV [EDX+MEMBER.Offset],EAX
        Invoke EaBufferReserve::,MemberAdd ; Temporary buffer for names concatenation.
        BufferStore EAX,[EDI+MEMBER.NamePtr],[EDI+MEMBER.NameSize]
        JC .F9314:
        BufferStore EAX,[ESI+MEMBER.NamePtr],[ESI+MEMBER.NameSize]
        JC .F9314:
        PUSH ESI
          BufferRetrieve EAX
          Invoke EaBufferRelease::,EAX  
          PoolStore [EBX+SSS.PgmPool],ESI,ECX
          MOV [EDX+MEMBER.NamePtr],EAX
          MOV [EDX+MEMBER.NameSize],ECX
        POP ESI
        BufferStore [EBX+SSS.MemberBuffer],EDX,SIZE#MEMBER
        JNC .80:
 .F9314:Msg cc=C,'9314',MemberAdd
        POP ECX
        JMPS .90:        
 .80: POP ECX
      ADD ESI,SIZE#MEMBER
      SUB ECX,SIZE#MEMBER
      JA .20:        
 .90:EndProcedure MemberAdd
↑ MemberCreate SssPtr, StmPtr
MemberCreate creates a symbol for each named structure member. It is used when DS statement is executed both inside a section or inside a structure.
MemberCreate is invoked in ctxSTRUC+ctxExpansion context, local member names will be completed with context namespace.
Input
SssPtr ^SSS Structure whose members from Sss.MemberBuffer are created.
StmPtr DS statement which provides default properties of created symbols.
Output
CF=0
Error
CF=1 Errors are reported with macro Msg.
Example
Inner STRUC .Inn1 DD D ; Member of Inner structure. DD D ; Unnamed data do not create structure member. ENDSTRUC Inner Outer STRUC .Out1 DD D; Member of Outer structure. .Out2 DS Inner ; Structured member of Outer structure. ENDSTRUC Outer Var DS Outer ; Definition of structured memory variable. ; Previous statement will create symbols Var, Var.Out1, Var.Out2, Var.Out2.Inn1
See also
MemberAdd, MemberUpdate.
Invokes
SymCreate
Invoked by
PseudoData
MemberCreate Procedure SssPtr, StmPtr
McStm  LocalVar Size=SIZE#STM ; Fake statement which provides info for creating a symbol.
     LEA EBX,[%McStm]
     CopyTo EBX,[%StmPtr],Size=SIZE#STM ; Initialize temporary fake statement.
 .10:MOV EDX,[%SssPtr]  ; ^SSS structure.
     MOV EDI,[EBX+STM.OffsetLow]
     TEST EDX
     STC
     JZ .90:
     BufferRetrieve [EDX+SSS.MemberBuffer]
     TEST ECX
     JZ .90: ; Do nothing if no named members are in buffer.
 .50:PUSH ECX,ESI,EDI ; ESI=^MEMBER.
       MOV ECX,[ESI+MEMBER.NameSize]
       MOV EDX,[ESI+MEMBER.Size]
       ADD EDI,[ESI+MEMBER.Offset]
       MOV EAX,[ESI+MEMBER.Status]
       MOV ESI,[ESI+MEMBER.NamePtr]
       MOV [EBX+STM.Size],EDX
       MOV [EBX+STM.OffsetLow],EDI
       MOV [EBX+STM.Status],AL
       MOV EAX,stmLabelIsPublic
       AND EAX,[EBX+STM.Status]
       OR  EAX,symDefined
       Invoke SymCreate::,EAX,ESI,ECX,EBX
       TEST EAX
       JZ .80:
       SetSt [EAX+SYM.Status],symReferenced ; Member of a structure shouldn't report W2101.
.80: POP EDI,ESI,ECX
     ADD ESI,SIZE#MEMBER
     SUB ECX,SIZE#MEMBER
     JA .50:
 .90:EndProcedure MemberCreate
↑ MemberUpdate SssPtr, StmPtr, OutEmitBuffer, OutRelocBuffer
MemberUpdate copies data from Sss.EmitBuffer to OutEmitBuffer , updating matching members by keywords in Stm.KeyBuffer.
It is used in structured data declaration (pseudoinstruction DS).
Input
SssPtr Pointer to structure which is instantionized (SSS).
StmPtr is the parsed statement which defines the structured memory variable. It may have keywords whose value updates members of the structure.
OutEmitBuffer reserved empty BUFFER , allocated by caller.
OutRelocBuffer reserved empty BUFFER , allocated by caller.
Output
OutEmitBuffer is filled with structure data, updated with statement's keyword values. Occupied size equals to Sss.EmitBuffer.
OutRelocBuffer is filled with relocations of static data used in this structured memory variable. Their origins are related to the beginning of emitted structure.
Error
reported with macro Msg.
See also
MemberAdd, MemberCreate.
Invokes
EaBufferRelease EaBufferReserve ExpEvalData
Invoked by
PseudoData
MemberUpdate Procedure SssPtr, StmPtr, OutEmitBuffer, OutRelocBuffer
MuEmitBuffer  LocalVar ; Temporary buffer used in keyword value evaluation. 
MuRelocBuffer LocalVar ; Temporary buffer used in keyword value evaluation.
      Invoke EaBufferReserve::,MemberUpdate
      MOV [%MuEmitBuffer],EAX
      Invoke EaBufferReserve::,MemberUpdate
      MOV [%MuRelocBuffer],EAX
      MOV EDI,[%SssPtr] ; Instantionized structure.
      MOV EBX,[%StmPtr] ; Definition statement with keywords.
      TEST EDI
      STC
      JZ .99:
      BufferRetrieve [EDI+SSS.EmitBuffer] ; Template data of the structure, including its static defaults.
      BufferStore [%OutEmitBuffer],ESI,ECX
      Msg cc=C,'9314',MemberUpdate
 ; OutEmitBuffer is initialized with STRUC defaults. Now its members will be updated by Stm keywords.
 ; Outer loop .10: .. .80: walks through statement keywords, and for each keyword 
 ;                             an inner loop .20: .. .30: searches for the member.
      BufferRetrieve [EBX+STM.KeyBuffer]
      LEA EDX,[ESI+ECX] ; ESI..EDX are keyword records (4*DD).
 .10: CMP ESI,EDX
      JNB .90:
      PUSH EDX,ESI
        MOV EDI,[%SssPtr]
        MOV EBX,ESI ; EBX is now keyword record (4*DD).
        BufferRetrieve [EDI+SSS.MemberBuffer]
        LEA EDX,[ESI+ECX] ; ESI..EDX are MEMBER records.
  .20:  CMP ESI,EDX
        JNB .30:
        Compare [EBX+0],[EBX+4],[ESI+MEMBER.NamePtr],[ESI+MEMBER.NameSize]
        JE .40:
        ADD ESI,SIZE#MEMBER
        JMP .20:
  .30: ; Keyword is not in memberlist.
        Msg '2612',EBX,EDI,PgmStatus=pgmLastPass ;  "!1S" is not member of structure !2S. Ignored.
        JMP .80: ; Continue with the next keyword.
  .40: ; Matching member found. Keyword value at [EBX+8],[EBX+12] will safely rewrite
       ; corresponding contents of OutEmitBuffer at [ESI+MEMBER.Offset].
        BufferClear [%MuEmitBuffer]
        BufferClear [%MuRelocBuffer]
        Invoke ExpEvalData::,[%MuEmitBuffer],[%MuRelocBuffer],[EBX+8],[EBX+12],[ESI+MEMBER.Status],[%StmPtr]
        JC .80:
        MOV EAX,[ESI+MEMBER.Offset] ; Relative offset inside the structure contents (0..value size).
        MOV EDX,[ESI+MEMBER.Size] ; Maximal size that may be rewritten.
        BufferRetrieve [%MuEmitBuffer] ; ESI,ECX is proposed new value.
        CMP ECX,EDX
        JBE .50:
        LEA ECX,[EBX+8]
        Msg '2613',ECX,[%SssPtr],EBX ; Value "!1S" does not fit to structure member !2S.!3S. Truncated.
        MOV ECX,EDX
  .50:  MOV EDI,ESI
        MOV EDX,ECX ; EDI,EDX is now truncated new value.
        BufferRetrieve [%OutEmitBuffer]
        ADD ESI,EAX ; Add member offset.
        CopyTo ESI,EDI,Size=EDX ; Rewrite (truncated) data in OutEmitBuffer.
        BufferRetrieve [%MuRelocBuffer]
        JECXZ .80:
  .60:  ; Each relocation in keyword value will be patched with member offset in EAX.
        ADD [ESI+RELOC.OrgLow],EAX
        ADCD [ESI+RELOC.OrgHigh],0
        BufferStore [%OutRelocBuffer],ESI,SIZE#RELOC
        Msg cc=C,'9314',MemberUpdate
        ADD ESI,SIZE#RELOC
        SUB ECX,SIZE#RELOC
        JA .60:
  .80:POP ESI,EDX
      ADD ESI,16 ; Next keyword.
      JMP .10:
[.data]
           ALIGN DWORD
.TempReloc DS RELOC ; Swap area for .SortByOrg.
[.text]

.SortByOrg:: PROC ; ShellSort callback for sorting relocations.
                  ; Input: ESI and EDI are RELOC objects to compare by origin.
                  ; If they are in wrong order, procedure performs their swap and returns CF.
                  ; Also called back from PfOutput.
       MOV EAX,[EDI+RELOC.OrgLow]
       MOV EDX,[EDI+RELOC.OrgHigh]
       CMP EDX,[ESI+RELOC.OrgHigh]
       JA .OK:
       JB .Swap:
       CMP EAX,[ESI+RELOC.OrgLow]
       JAE .OK:
 .Swap:MOV EDX,MemberUpdate.TempReloc
       CopyTo EDX,ESI,Size=SIZE#RELOC
       CopyTo ESI,EDI,Size=SIZE#RELOC
       CopyTo EDI,EDX,Size=SIZE#RELOC
       STC
 .OK:  RET
      ENDP .SortByOrg

 .90: ; %OutRelocBuffer was filled with relocations from updating keywords.
    ; However, not updated members of the structure may have its own relocations,
    ; they will be appended to %OutRelocBuffer unless a relocation already exists
    ; on the same origin.
      MOV EDI,[%SssPtr]
      BufferRetrieve [EDI+SSS.RelocBuffer]
      JECXZ .98:
 .92: PUSH ECX,ESI
       MOV EBX,ESI ; Relocation from the structure.
       MOV EDX,[EBX+RELOC.OrgLow]
       BufferRetrieve [%OutRelocBuffer]
       JECXZ .95:
 .94:  CMP EDX,[ESI+RELOC.OrgLow] ; Compare with relocation from keywords.
       JE .96: ; Relocation with this origin was already stored in OutRelocBuffer, skip.
       ADD ESI,SIZE#RELOC
       SUB ECX,SIZE#RELOC
       JA .94:
 .95:  ; None from relocations already stored in %OutRelocBuffer has the same origin EDX as EBX.
       BufferStore [%OutRelocBuffer],EBX,SIZE#RELOC
       Msg cc=C,'9314',MemberUpdate
 .96: POP ESI,ECX
      ADD ESI,SIZE#RELOC
      SUB ECX,SIZE#RELOC
      JA .92:
 .98: Invoke EaBufferRelease::,[%MuRelocBuffer]
      Invoke EaBufferRelease::,[%MuEmitBuffer]
      ; Contents of OutRelocBuffer must be sorted by origin.
      BufferRetrieve [%OutRelocBuffer]
      JECXZ .99:
      MOV EDI,SIZE#RELOC
      MOV EAX,ECX
      CDQ
      DIV EDI
      ShellSort ESI,EAX,EDI,.SortByOrg
.99: EndProcedure MemberUpdate
 ENDPROGRAM member

▲Back to the top▲