NESASM does everything ABS unless a < explicitly indicates ZP, which I would agree is wrong, but I think "backwards" is not the right way to describe this. Making everything ZP unless explicitly marked ABS would be equally wrong.
Actually I think it would be even more wrong. At least ZP instructions will still function the same way but slower if incorrectly assumed as ABS. The opposite is not true. You're now mandating annotations of probably most memory accesses in a program just for it to function?? That's what I mean that I don't understand how this would be implemented.
We're talking about ca65 though. ca65 will reduce anything with known 8-bit sized value to ZP, and assume ABS wherever it is unknown (or known to be larger), but either assumption can be explicitly overridden by z: or a: if needed (generally only rarely). This seems almost ideal to me, except for the fact that ca65 is single pass, so anything you want to auto-assume ZP has to be declared as ZP before the instruction in some way, of which there are many options:
- Using an explicit value.
- Placed in a segment that is marked zeropage.
- < or > operator result is correctly assumed to be byte sized.
- Imported as a zeropage symbol (.importzp)
- A z: prefix on use.
In my experience this produces the "right" thing with minimal fuss, as long as you keep the single pass concept in mind when working. With conventions and habits that remember to declare variables above their use, the issue of selecting operand size almost entirely disappears, and the z: and a: prefixes give you safe ways to override it with range checking that will tell you if you made a mistake!
(I don't offhand know how ASM6 does things, and its documentation doesn't seem to explicitly state what it does.)
Anyhow, sorry this seems to be quite a digression. The discussion was talking about appropriate practice for using < or z: etc. because the question was how does ca65 know about sizes of values. What a theoretical assembler should do is kind of a completely different problem.