Add with carry 2026-10-24
For -bit operands, an add with carry operation forms , retains its residue modulo , and outputs its arithmetic carry. Adding low limbs first and feeding each arithmetic carry into the next limb implements multiword unsigned addition. With , the identities and combine into .[ref]
A subtract with carry instruction consumes the no-borrow carry flag. Its arithmetic is . Hence a low-limb subs followed immediately by a high-limb sbcs propagates exactly the low subtraction's borrow.
For example, with the same limb assignment as in (c):
subs r0, r0, r2
sbcs r1, r1, r3
It uses an ordinary 32-bit adder by complementing every bit of the subtrahend and adding the incoming arithmetic carry. For , the unreduced adder sum is
If this is , rearrangement gives . Thus both the result and outgoing no-borrow flag have the required meanings. With incoming arithmetic carry one this becomes ordinary subtraction.[ref]
Use the AAPCS32 convention: r0 holds the input address, r1 the length, and r0 receives the result. The following Thumb instruction set assembly language uses only scratch processor registers, so no callee-saved registers need saving. Assume the array is valid, halfword-aligned, and has nonnegative length; for the mathematical sum assume it fits a signed 32-bit two's complement integer.
.syntax unified
.thumb
.thumb_func
sum16:
    movs r2, #0             @ accumulated sum
    cmp  r1, #0
    ble  .Ldone             @ empty array; also returns 0 if n < 0
.Lloop:
    movs r3, #0             @ Thumb signed load needs a register offset
    ldrsh r3, [r0, r3]      @ signed halfword at a; offset read before r3 changes
    adds r2, r2, r3         @ include this signed value
    adds r0, r0, #2         @ advance by one short, not one byte
    subs r1, r1, #1         @ one fewer element remains
    bne  .Lloop
.Ldone:
    movs r0, r2             @ result register
    bx   lr                 @ leaf routine: lr was not overwritten
After iterations, the loop invariant is that r2 contains the first elements' sum, r0 points to element , and r1 is . The sign extension in ldrsh supplies the correct signed addend. One iteration preserves this loop invariant, and the decreasing remaining length proves algorithm termination. For the seven-element calls, the sum lies between and , so it fits. For longer arrays that overflow, these instructions compute the sum modulo ; that is not a claim about defined signed C programming language overflow behavior. The operand forms are those of the paper's reference sheet.[ref]
Use r0 for the argument and result. With 32-bit integers and pointers, the three fields have byte offsets 0, 4 and 8. Assume an acyclic finite binary tree, no concurrent mutation, a valid aligned call stack, and no signed integer overflow in any evaluated sum. These are representation and arithmetic assumptions, rather than properties of arbitrary C programming language implementations.
.syntax unified
.cpu cortex-m0
.thumb
.global sum_rec
.thumb_func
sum_rec:
    cmp  r0, #0
    beq  .Lempty
    push {r4, r5, r6, lr}    @ 16-byte frame; r6 is alignment padding
    movs r4, r0              @ retain this invocation's node
    ldr  r5, [r4, #0]        @ running value begins with its label
    ldr  r0, [r4, #4]
    bl   sum_rec             @ r0 = left subtree sum
    adds r5, r5, r0
    ldr  r0, [r4, #8]
    bl   sum_rec             @ r0 = right subtree sum
    adds r0, r0, r5
    pop  {r4, r5, r6, pc}    @ restore caller state and return
.Lempty:
    movs r0, #0
    bx   lr
The node and partial sum are held in callee-saved registers r4,r5. Each recursive invocation saves its caller's values before replacing them, so a child returns with the parent's values intact. Saving lr preserves the return address across the two bl instructions. Caller-saved registers may be overwritten by a child; no parent value is left live only in them. Pushing four words maintains eight-byte stack alignment at recursive calls.[ref]
Correctness follows by structural induction. An empty subtree returns zero. For a nonempty subtree, assume both recursive calls return their respective label sums. The final addition then combines the node's label with exactly those two sums, so r0 returns the sum of all labels. The instruction forms and field offsets fit the short load and arithmetic encodings.[ref]
For a 32-bit machine word and , use a left bit shift followed by a logical right shift:
lsls r1, r0, #(32-k)
lsrs r1, r1, #(32-k)
The left shift discards all but the lowest bits and moves those retained bits to the top. The logical right shift returns them to their original positions and fills the rest with zero. Hence r1 contains , the remainder identified in (b). For the remainder is zero; for it is , so these endpoints can be handled directly.
On a reduced instruction set computer, a bit mask such as may not fit an instruction's immediate field. Masking may therefore require materializing the constant in another processor register, possibly using several instructions or a memory load. Small shift counts are directly encodable, so the two shifts can save code space, a temporary processor register, or a load. This is an architecture-dependent advantage, rather than a universal speed claim. The source's compact instruction forms support these immediate shifts, while their bitwise AND form takes its other operand from a processor register.[ref]
A processor design using a relatively regular instruction repertoire and explicit restrictions on operand forms. Immediate constants may have limited encodings, so extracting low bits with two bit shifts can avoid constructing a large bit mask in a temporary processor register. The benefit depends on the actual instruction set. A compact example appears in the Thumb 16-bit instruction set quick reference by Arm, whose logical bitwise AND instruction uses a processor register operand while shifts accept small immediate counts.
Subtract with carry 2026-10-24
With the ARM architecture family's no-borrow convention, subtract with carry forms . The same adder used for addition can form . If its output is , rearranging proves . Thus complementing the second operand implements both the result and the correctly chained borrow information.[ref]
Thumb instruction set 2026-10-24
A compact instruction encoding for the ARM architecture family, with sixteen-bit encodings and, in later versions, additional thirty-two-bit encodings. Operand restrictions depend on the selected architecture. The original sixteen-bit signed halfword load uses a register offset, whereas an ordinary halfword load also offers an immediate offset.[ref]