There are indeed various helper macros but what Joe is asking for is a way for Nasm to automatically handle the fact that any reference to a field in a struc be implicitly associated with the base register established via some "USING" mechanism. The idea is not new but it's implementation in Nasm would be. I actually like the suggestion but struggle with it's ramifications.
Of course the idea is not new, it's at least from the 1960s!
Actually the USING mechanism works for code as well as data and it has many other options. I know I could personally use it for structures in NASM even in the small amount of code I have written until now. I don't know enough about x86 or NASM to know where else it should be used. Maybe you can think of some. But we have a very different environment, in some ways I understand it is more similar to DOS than to modern Win/Linux/Unix because we can only reference 4k of code or data at a time (like segmentation sort of, but not really) so USINGs for us are an essential part of life because we always have to specify the base address of code or data. But it's also essential to make the code cleaner and make maintenence easier when referring to control blocks. For example in x86 if you have a large control block and you have many references to base+fieldname and you need to change the base for some reason, let's suppose you're going from x86 to x64 and you decide to use one of the new registers, now you have to manually change every line of code. That's prone to errors, either by missing a few lines or by changing lines that shouldn't be changed. If you had an assembly directive to base all of your stucture references off of in a specific section of code, that huge PITA change just became a one-liner and it's certain to work like it should with none of the risk associated with changing line by line. Note, one important aspect of the directive has to be that it has a scope. USING and DROP go together. Just like you need to be able to say "at this point in the source file, start assigning the base address by using *this* register" you also have to be able to say, "at this point in the source file, stop using *this* register as a base register". Specific reasons include needing to use the register for something else at that point in code, and it's no longer pointing to your structure so it's unsafe to let the assembler stumble over a line that got left in and assemble it incorrectly. Bad code should get flagged. Since in x86 there is always a shortage of registers, it's very likely we'll use a register to map a structure and then pretty soon we'll stop doing that and reuse the register for some other purpose, or even to map another, different structure. If we don't have a way to undo the prior USING then we'll be in bad shape.
Very simple examples:
USING R11, MYSTRUC
.
mov R11, 0 <- Should Nasm account for this or caveat emptor?
.
mov RAX, [MyFieldA]
I'm not sure what this example shows...the USING should have the area name followed by the register name, in this case USING MYSTRUC,R11. If that's what you meant then are you saying, what happens if I code an instruction and the base address of the area I am mapping got set to zero by mistake? Then yes, caveat emptor. And, this is an essential part of how it
should work because you may need to map areas from zero in some cases. I don't know about x86 but in MVS we do this all the time to navigate control blocks that are defined to exist at virtual address 0. Anyway, the whole thing has to be based on the assembler helping you and not doing something
to you by trying to outsmart you. The assembler should blindly accept whatever address you assign as the base, and it would be nice if base+offset or base-offset was also an option rather pure base. That would allow you to use structures to map a stack frame and that would be a super nice cleanup of negative references in code that use magic number and are hard to maintain. With some kind of USING/DROP support, that code can be written cleanly and increase readability and therefore code quality.
If you had a struct that includes the length of the struct as an equate, you should be able to load a gpr with the base address, subtract the struct length equate value, and then do a USING structname,gpr. Then you reference fields in the stack frame by name, with no risk of wrong offset values. You can do that now of course, but you still have to code base+ fieldname rather than just fieldname.
Or how about
USING R11, MYSTRUCA
USING R12, MYSTRUCB ; <-- Allow multiples?
.
mov RAX, MyFieldX ; <-- Defined in both MYSTRUCA & MYSTRUCB
.
USING MYSTRUCA,R11
USING MYSTRUCB, R12, ; <-- Allow multiples?
I would have to go look and see how this works today. I know originally all field names had to be unique in an assembly. So this problem couldn't happen. Today they may allow qualified names, but I don't use them because I think it can cause confusion and if not confusing, more typing, which kind of goes against coding in assembler. If NASM already supports qualified names then the simple answer is it should continue to work like it works now. If that reference is a qualified name and it would have to be qualified in code, it should have to be qualified in your example also. I don't know why there should be any difference. Did I miss something, or does that relate to what you are talking about?
Granted, both cases are easily handled with warnings/errors, but I'm sure there are other scenarios that need accounted for. Regardless, the request should probably be posted to Suggestions or filed as a Bug Tracker Feature Request as it deserves further consideration.
I'm impressed with you guys and thanks for the helpful attitudes. I am obviously not qualified to put in a formal request since I don't know enough about how NASM works (which is why the original post was "can we do this" rather than "why don't you add a feature") and I would miss important details. But if you can help me formulate a request that encompasses what I am asking for on a functional level that makes sense in NASM that would be excellent.
Thanks Cyrill and Rob!