## Are gas macros powerful enough to define a struct with ## fields? I was reading the armasm manual and it gives ## examples like ## MAP 0, r9 ## FIELD 4 ## Lab FIELD 4 ## LDR r0, Lab ; equivalent to LDR r0, [r9, #4] ## and they also have registerless fields that you use like ## LDR r0, [r9, #Lab] ## So the MAP directive sets the {VAR} counter to 0, and the ## FIELD directive captures its value and increments it. I ## was thinking maybe I could define some macros in gas and ## get the same effect. And it turns out that I can. .macro map .set map_counter, 0 .endm .macro field size, label .ifnb \label # if nonblank .set \label, map_counter .endif .set map_counter, map_counter+\size .endm ## You probably want to know the size of these records if ## you’re defining them. .macro mapsize label .set \label, map_counter .set map_counter, "not defining a map" .endm map field 8 field 4 foo field 4 bar field 1 q field 1 u field 1 a field 1 k field 8 biggie field 8 burger mapsize struct1 map field 1 del field 3 elf field 4 dunno mapsize struct2 .data .byte foo, bar, q, u, a, k, biggie, burger, del, elf, dunno, struct1, struct2 ## With this you can plausibly define nested structs. map field 4 year field 2 month field 2 day mapsize datesize map field datesize startdate field datesize enddate mapsize twodates ## You can use these in instructions: .text mov %rax, year(%rbx) mov %rcx, (enddate + month)(%rdx) ## However, you can't do anything like this: .set rdxmonth, "month(%rdx)" mov %rdi, rdxmonth ## That generates a reference to a symbol named “month(%rdx)”, ## which is not at all the intended effect. You can of course ## do this: #define rdxmonth month(%rdx) mov %rdi, rdxmonth ## but you can't generate #defines from a .macro like `field`. ## You could use explicit CPS: .macro rdxday insn:vararg \insn day(%rdx) .endm rdxday mov %rsi, ## but that’s really a pain, especially to update the field, ## though explicit CPS doesn’t let us down and this does work: .macro mov_from_rsi dest mov \dest, %rsi .endm rdxday mov_from_rsi ## Can we actually define month(%rdx) as a label? "month(%rdx)": ret ## Yes, yes we can.