This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Proposal: GAS, nested structures


Hi all.

I'd like to use .struct for a lot of things, but I find it very limited, when comparing to the directives similar to .struct I've used in assemblers earlier.

.struct can be implemented by using macros, so it's not really "really needed". Also, it's difficult to find documentation on how to use it.

The assemblers I've used earlier include Hisoft Gen(ST/TT) and the old MPW Assembler.

The way GenST/GenTT implemented 'struct' was similar to GAS, but for some reason, I think it was easier to 'overview'.
The directives were: "RSSET", "RSRESET" and "RS". "RS" was an abbreviation for "Reserve Space".
__RS is a reserved symbol.

            RSSET       <value>     ; __RS = <value>
            RSRESET                 ; __RS = 0
label1:     RS.B        7           ; label1 = __RS : __RS = __RS + 7
label2:     RS.W        3           ; __RS = __RS & ~1 : label2 = __RS : __RS = __RS + 3 * 2
            RS.B        17          ; __RS = __RS + 17
buffer2:    RS.B        __RS        ; buffer2 = __RS : __RS = __RS + __RS
            RS.B        1           ; __RS = __RS + 1
label3:     RS.L        0           ; __RS = __RS & ~1 : label3 = __RS

RS and friends work very much like the EQU directive. Once the label value was set, it could not be changed.

I once wrote an assembler, which extended RS and RSSET so that if RSSET or RSRESET was given a label, this was used as a structure identifier.
I also invented the '.P' type (for pointer), so that the user could be sure that a variable could contain a pointer, plus '.F' and '.D' for floats and doubles.

The difference between GAS and Gen is that GAS uses an absolute section, and you can not say "I want to advance the location counter 4 x 32 bits".
Yes you can. You can use .space. But it's much easier to use the RS style (which can be implemented using macros, except from the important extension).

That was 'RS' and friends, simple and easy to use. Now the 'RECORD' from MPW Assembler is also quite simple, but much more powerful:


Point   RECORD      0
x:      DS.W        1
y:      DS.W        1
        ORG         x
xy:     DS.W        2
        ENDR

To use the above 'Point', you would just type...
            move.w      Object.x(a0),d1

What's special about 'RECORD' is that you could, unlike .struct, create structures that contained a name that was already used in other structures.
This means you could have another structure below 'Point', like this:

Object  RECORD      0
x:      DS.W        1
y:      DS.W        1
w:      DS.W        1
h:      DS.W        1
        ORG         x
xy:     DS.W        2
wh:     DS.W        2
        ENDR

My proposal is to go with an extended mix of 'RS' and 'RECORD', so that you can...


Point:  .record     0
        .equ        xy,.
x:      .rs.w       1           ; reserve word (32-bit) for x coordinate
y:      .rs.w       1
        .endrec

Size:   .record     0
        .equ        wh,.
w:      .rs.h       1           ; reserve halfword (16-bit) for width
h:      .rs.h       1
        .endrec

Object: .record     0
        .equ        xy,__rs
origin: .rs.Point   1           ; insert one structure named 'Point'
        .equ        wh,__rs
size:   .rs.Size    1           ; insert one structure named 'Size'
        .endrec

One could then also 'tail' another record:

ColOb:  .record     Object
        .rs.h       3           ; a RGB color
        .endrec

ProgIn: .record     ColOb       ; a progress indicator
        .rs.d       1           ; floating point double
        .endrec

TextOb: .record     ColOb
string: .rs.p       1           ; reserve pointer
        .endrec

Misc:   .record     TextOb
        .even                   ; same as .align 2
fps:    .rs.f       1           ; floating point single
        .rs.o       1           ; 8-byte (d is used for floating point doubles)
name:   .rs.b       10          ; reserve byte
        .endrec


...In other words, the above would allow for structures containing structures, which we've seen in C is very useful. ;)
So the single character 'sizes' could be reserved for the assembler.
Alternatively, keywords could be created instead of adding a .size-suffix to the .rs directive.
        .rbyte
        .rhword
        .rword
        .rptr
        .rfloat
        .rdouble
        .rrecord                ; (so we can put a record inside a record)

I think it would be wrong to recycle .struct and .endstruct here, because they already have a defined behaviour, so does '.byte', '.word', etc.
Those behaviours differs too much from the proposed 'record'. Eg. '.byte' inserts a constant value; it does not 'reserve space'.

In short: .record / .endrec does not output any code. It does not reserve any space in any sections.
One could simplify it into saying that all it does is generate a kind of equates, which are 'separated by dots', records are recognized as 'records' not equates.

Now, what would really make a 'revolution', would be if it was possible to create a header file, which could be used in both C sources and assembly sources.
-Not directly, because that'd probably be too difficult, but in C, you have the #define directive, so you don't have to use braces for instance.
#define could be used with the assembler as well, but 'native' assembler macros would be sufficient in this case.
So with the above proposal, I think it's possible to write a header file, which could be used from both C and assembly sources for simple structures.
(I'm thinking "microcontrollers" here).

I'd like to leave my proposal flexible and open, so that the developers have some room for creativity.
Feel free to comment. ;)


Love
Jens


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]