Look at this:
@ The assembler screws this
.set RCH_POST_ORIGIN, RCH_PRIOR_ORIGIN + RCH_PRIOR_SIZE
@ Here, RCH_PRIOR_SIZE was clearly 0x1C (I even had .long RCH_PRIOR_SIZE as one of the lines and it outputs correctly right up until it is used in this equation, just after which is appears as -4 as though its use in the expression modified the value)
What's clearly happening from my debugging is the variable RCH_PRIOR_SIZE is being randomly modified before it's used in the evaluations of the expression. Oddly enough, inserting debugging lines to help me find the integers in the output binary actually causes the binary output to be correct where it usually wouldn't be, and removing that debug output (which is just in the form of ".long 0xEFBEADDE" <- DEADBEEF) caused it to fudge again, implying that the processing related to directives has some severely awkward edge case.
I could file a bug report but it couldn't be handled soon enough. In the mean time I'd like suggestions as to an alternative method of calculating these values (which are defined using the ".set" directive for each variable elsewhere in the source; don't suggest using ".equ" instead: I tried that too on the grounds that supposedly ".equ" creates a "symbol" and not a "variable" which I guessed might be different enough for the former to work where the latter clearly didn't). Or, if you know of a better assembler altogether, that'd be great.
FUCK devkitARM. I bet you they still have the ldrh/ldsb confusion bug in the damn thing. Seriously, how stupid do you have to be to use a user defined variable as a scratch register for your program (which is what it looks like it's doing)? I defined it for MY program. Get your shitty code off my variables' nuts!
Edit: Turns out they DID fix the ldrh/ldsb confusion. I just checked and it wasn't even a bit off; how the hell did the two get confused?
In the mean time, I'm getting around this bug by using a larger expression that calculates what RCH_PRIOR_SIZE should be in the expression on the fly instead of reusing it from its last calculation, since doing the latter, as I've said, causes the stupid assembler to temporarily use the incorrect value for that variable and botch the output.
Edit: Also, this
bl SUBTRACT_FUNCTION - RCH_PRIOR_ORIGIN + RCH_PRIOR_START
Causes a warning despite not only being perfectly valid, but yielding the desired output, as well.