Negation of 64-Bit Numbers with 32-Bit Registers

Coded in Thumb (ARM) | July 27, 2011 | Download
Many assembly programs require the use of large negative numbers, but sometimes the system only supports 32 bits. Therefore, negating 64-bit numbers in assembly can no longer be done with a NEGS command, and extra checks and steps are needed.
Assume the 64-bit number comes in R0 and R1, with R0 containing the bottom half the number, and R0 containing the top half. We first compare the top half, R1, to 0 (the top half will contains sign bit).
CMP     R1, #0
BGE    _end
If R1 is greater than 0, the number is positive. We can directly skip the negation.
NEGS    R0, R0   ; Negate bottom half
NEGS    R1, R1   ; Negate top half
If the number is negative, the first step is to negate both the top and bottom half of the number. It isn't simple though, since various problems occur with the bottom half after negation.
MOVS    R7, #0s
SUBS    R7, #1   ; R7 now contains all F's
CMP     R1, R7   ; If top half isn't all F's,
BNE     _sub     ; then subtract 1
CMP     R0, #0   ; Or, if the bottom half isn't all 0's
BNE     _sub     ; then also subtract 1
B       _end     ; Otherwise end
_subs
SUBS    R1, #1   ; Subtract 1 from the top half
If the top half of the number isn't all F's, then 1 must be subtracted from it, since the using NEGS on a register flips all its bits and adds 1. Not doing so would give an incorrrect result. We also do this if the bottom half isn't all 0's. The only case in which we will not have to do the subtraction correction is if the top half of the number contains all F's and the bottom half contains all 0's. This represents the number 232, or 4,294,967,296.