Interesting observation, Madanra! I think it's a bug report...
I have developed a theory of what's happening. Going back to 2.02, I get "error: symbol 'dataend' not defined before use". The argument to "equ" (and a few other cases) is, or was, a "critical expression". The value needs to be known on the "first pass", or actually on the "next to last" pass. Nasm won't handle a "forward reference" in this position. Adding the "-O" switch enables multiple passes, so eliminates this error (but still gets the "divide by zero").
As of 2.03, unless I'm mistaken, we take an extra pass to resolve forward references, even if multiple passes aren't enabled for optimization purposes. A Good Thing, generally, I think.
Apparently, "spt" is being "provisionally evaluated" as zero on the first pass, in this case. Not a problem, we evaluate it correctly on subsequent passes... unless we divide by it! I'm thinking the "fix" for this may be to tag "spt" as a forward reference, so we don't attempt to divide by it (instead of - or along with - evaluating it as zero?). This is apparently what happens when you do "dd 32/sector(dataend)" - (doing "spt" as a "%define" rather than an "equ" is just a "cut-and-paste", so is equivalent to this).
We'll see if we can get the real developers to take a look at this. In the meantime "don't divide by the result of an 'equ' if it's a forward reference". That's my theory.
Incidentally, "( (b) - $$) >> 9" truncates. You might want to do "( (b) - $$ + 511) >> 9" to "round up". If your "payload" is padded to an even number of sectors, it isn't a problem. Just a thought...
Thanks for the feedback! Apparently no one noticed this problem before!
Best,
Frank