This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Assembler directive to compute structure members' offsets at assemble time

Hello All,

I am looking for the Assembler directive to codify the structure members' address offsets in portable (auto-recomputable) way. Only at assemble I want the assembler to compute the offsets rather thanme  hard-coding their offsets into my assembly program.  For example, the members of a structure are accessed by the following manner, where their offsets like 0 and 1 (array indices) are used:

        MOV       AL,*+XAR5[0]          ; |32| 

        SUB       AL,*+XAR4[1]          ; |32| 

I have given below a sample 'C' program and the compiler generated assembly line code for the same.
How to achieve this? Can someone suggest a solution?
Thanks
Sayee

struct mystr {

int a, b;

} X;

struct mystr *p = &X;

main()

{

   p->a = p->a -p->b;

}

a portion of the compiled code in assembly looks like below: 

        MOVL      XAR5,@_p            ; |32| 

        MOVL      XAR4,@_p            ; |32| 

        MOV       AL,*+XAR5[0]          ; |32| 

        SUB       AL,*+XAR4[1]          ; |32| 

  • Your best bet is to define the structure in a C header file, then include it in your assembly with the .cdecls directive.  Please see here for details.

    Thanks and regards,

    -George

  • Hello George,

    My question itself is not about  defining the structures in 'c' header files and including the header file with  cdecls directive in the asm file. It is only about accessing the members with the assembly statements as given below.  It is ok for a compiler genrated code from 'C'. But, XAR4 and XAR5 registers use hard-coded indices to access the members. At a later date if I modify the structure to include more elements, I have to fix my assembly code all over. Am I clear?

    My question is simple: how do I code those assembly lines, with indices being referred to logical member-offsets which would get resolved at assembly time rather than physical (hard-coded) offsets.

    Thanks in advance,

    Sayee

    MOVL      XAR5,@_p            ; |32| 

            MOVL      XAR4,@_p            ; |32| 

            MOV       AL,*+XAR5[0]          ; |32| 

            SUB       AL,*+XAR4[1]          ; |32| 

  • You can use the names of the members instead of hard-coded constants.  This is described in the Assembly Language Tools User's Guide, in the section that documents the .struct directive.

    MOV AL,*+XAR5[mystruct.first]
    SUB AL,*+XAR4[mystruct.second]
  • Thanks for your suggestion. It works.

    I assume it should work in all places where the address offset are to be computed. Consider a case where there is a array of structures and you have a pointer in XAR2 pointing to the start of the first structure from which if you have to get address offset of the 3rd struture element's 2nd member how do you do it? As this is a assemble time constant, the assembler can evaluate. But how do we code in the logical level than physical hard-coded offset.

    can we code something like this? To put the quesion otherway, a built-in function like $sizeof(), $offset(struct.member) is needed. 

     MOV *+XAR2[3*$sizeof(MYSTRUCT) +MYSTRUCT.member_2], AL ; assembler error

    Thanks in advance,
    Sayee

  • If you are using the ".struct" directive in assembly code, you can put a label on the ".endstruct" directive.   When this label is evaluated, it evaluates to the size of the structure, as documented in the Assembly Language Tools User's Guide, in the section documenting the ".struct" directive.  There is also an example in the section "Symbolic Constants" in chapter "Assembler Description".

    If you are using the ".cdecls" directive to include a C header file, unfortunately this feature is not used, so I don't know how to implement a "sizeof" expression.

    I've submitted enhancement request SDSCM00039511 to add this feature for .cdecls

     

  • Today I learned that you can use $sizeof(structname) or $structsz(structname) to get the size of the structure, so this feature is already implemented.

    You indicated that the following instruction gives you an assembler error:

    Mokan Kanna said:
    MOV *+XAR2[3*$sizeof(MYSTRUCT) +MYSTRUCT.member_2], AL ; assembler error

    When I try this, I do not get an assembler error.  What is the exact text of the error message you get?