Yuriy F
Yuriy F

Reputation: 361

Nested STRUCT and UNION in x86 assembly language

I am trying to implement a c data structure in assembly language for a networking applicaton. NOTE: This is for an Assembly class project, so it needs to be in assembler!!!

Here is the c structure from MS docs:

typedef struct in_addr {
    union {
        struct {
          UCHAR s_b1;
          UCHAR s_b2;
          UCHAR s_b3;
          UCHAR s_b4;
    } S_un_b;
    struct {
          USHORT s_w1;
          USHORT s_w2;
    } S_un_w;
        ULONG S_addr;
    } S_un;
} IN_ADDR, *PIN_ADDR, *LPIN_ADDR;

Here is the code in assembly language:

in_addr STRUCT
    UNION S_un
        S_un_b STRUCT      ; an error here!
            s_b1 BYTE ? 
            s_b2 BYTE ?
            s_b3 BYTE ?
            s_b4 BYTE ?    
        S_un_b ENDS        ; an error here!

        S_un_w STRUCT      ; an error here!
            s_w1 WORD ? 
            s_w2 WORD ? 
        S_un_w ENDS        ; an error here!

        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

When I try to build, I get an error message (see above comments) that is either a syntax error (in the first 3 cases) or an "unmatched block nesting" as the last one. I tried to look through Intel documentation on whether a struct can be defined within a union but I couldn't find any definitive information.

I will appreciate Intel / MS documentation as much as a solution, if not more. I am new to Assembly language, although it is becoming somewhat of a hobby, weirdly.

Upvotes: 0

Views: 1712

Answers (1)

Yuriy F
Yuriy F

Reputation: 361

For anyone who has a similar question, the way you define a union that contains structs would be to define the structs beforehand.

Here is what I had originally:

in_addr STRUCT
    UNION S_un
        S_un_b STRUCT      
            s_b1 BYTE ? 
            s_b2 BYTE ?
            s_b3 BYTE ?
            s_b4 BYTE ?    
        S_un_b ENDS        

        S_un_w STRUCT     
            s_w1 WORD ? 
            s_w2 WORD ? 
        S_un_w ENDS        

        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

That won't compile, at least in masm. Here is what can be done:

S_un_b STRUCT
    s_b1 BYTE ? 
    s_b2 BYTE ? 
    s_b3 BYTE ? 
    s_b4 BYTE ? 
S_un_b ENDS

S_un_w STRUCT
    s_w1 WORD ? 
    s_w2 WORD ? 
S_un_w ENDS

in_addr STRUCT
    UNION S_un
        S_un_b<>
        S_un_w<>
        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

To then use this structure, use regular struct operations:

For example:

; To set S_addr
mov <in_addr instance name>.<union_name>.S_addr, 0h

Similar priciples can be applied to access BYTEs and WORDs.

Hopefully this will be helpful to someone with the same question.

Upvotes: 2

Related Questions