This is the mail archive of the
mailing list for the binutils project.
Proposal: GAS, nested structures
- From: Jens Bauer <jens-lists at gpio dot dk>
- To: binutils at sourceware dot org
- Date: Wed, 15 May 2013 07:59:24 +0200
- Subject: Proposal: GAS, nested structures
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
xy: DS.W 2
To use the above 'Point', you would just type...
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
xy: DS.W 2
wh: DS.W 2
My proposal is to go with an extended mix of 'RS' and 'RECORD', so that you can...
Point: .record 0
x: .rs.w 1 ; reserve word (32-bit) for x coordinate
y: .rs.w 1
Size: .record 0
w: .rs.h 1 ; reserve halfword (16-bit) for width
h: .rs.h 1
Object: .record 0
origin: .rs.Point 1 ; insert one structure named 'Point'
size: .rs.Size 1 ; insert one structure named 'Size'
One could then also 'tail' another record:
ColOb: .record Object
.rs.h 3 ; a RGB color
ProgIn: .record ColOb ; a progress indicator
.rs.d 1 ; floating point double
TextOb: .record ColOb
string: .rs.p 1 ; reserve pointer
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
...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.
.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. ;)