@struct

The @struct directive is used to simplify working with complex data types. "Structs" ultimately allow you to define offsets and lengths of data from a base address.

We'll start with a simple example:

@struct MyStruct
    field1 1
    field2 2
@endstruct

A @struct directive begins with a global label. In this example we create a struct named MyStruct. Then we provided a list of label-expression pairs ending with an @endstruct directive.

This has the same effect as writing:

@segment "ADDR"
@org 0

MyStruct:

@meta "@SIZEOF" "1"
.field1: @ds 0
@endmeta

@meta "@SIZEOF" "2"
.field2: @ds 1
@endmeta

@redefl MyStruct, 1 + 2

We can ignore the @meta and @endmeta directives for now and focus on the symbols added to the symbol table.

  • MyStruct holds the sum of all expressions for each label defined in the struct. This is the "size" (or length) of the struct in bytes.
  • MyStruct.field1 holds the offset of the label in bytes from the start of the struct. The offset of a struct is the sum of all expressions that came before it. Sice it is the first label in the struct, it has an offset of 1.
  • MyStruct.field2 as with the above, this label holds the offset of the label from the start of the struct. Since .field1 evaluates to 1, then .field2 is set to 1.

Structs provide a few other bits of syntactic sugar. Colons (:) following labels within the struct body are optional. Expressions can contain references to previously-defined labels in the struct. And you can use @db and @dw as synonyms for 1 and 2, respectively:

@struct MyStruct
    field1: @dw
    field2: .field1 + 1
    field3: @db
@endstruct

Finally, @align can be used in structs to add padding between labels just like you would do in normal code:

@struct MyStruct
    field1: @db

    @align 8
    field2: @db 
@endstruct