Machine instruction 2026-10-24
A machine-encoded operation executed by a processor. An assembly language mnemonic can denote one machine instruction or an assembler expansion into several.
MIPS architecture 2026-10-24
A family of reduced instruction set computer architectures. The classic 32-bit integer encoding has five-bit processor register fields, while many branch and jump instructions execute a branch delay slot. These conventions differ from later revisions and must be stated when presenting assembly language.
Let
r1:r0 hold the first operand, high limb first, and r3:r2 the second. In assembly language the addition can be written:adds r0, r0, r2
adcs r1, r1, r3The first instruction produces the low result and its arithmetic carry; the second immediately consumes that arithmetic carry while adding the high limbs. No intervening flag-setting instruction is permitted.
For a proof, put and denote the input limbs by . If the low addition gives and arithmetic carry , then . The high addition gives and final arithmetic carry , so . Multiplying the second identity by and combining yieldsThe processor register pair is the correct result modulo , and the final arithmetic carry records overflow beyond that unsigned width. If the mathematical sum fits in 64 bits, no reduction changes it.
Use four working processor registers by packing the growing quotient into the vacated low bits of the shifting dividend. The following is A32 assembly language with conditional execution, an allowed instance of the question's general 32-bit Reduced instruction set computer. It is not restricted to the sixteen-bit encodings in the supplied Thumb instruction set table. On entry
r0 is the dividend and r1 the positive divisor; r2 becomes the high remainder machine word and r3 counts iterations. The quotient is returned in r0 and the ordinary remainder remains in r2.mov r2, #0
mov r3, #32
loop:
adds r0, r0, r0
adcs r2, r2, r2
cmp r2, r1
subcs r2, r2, r1
adc r0, r0, #0
subs r3, r3, #1
bne loop
bx lrHere
subcs means conditional sub when arithmetic carry is set, without the flag-setting suffix. adc also preserves flags. Consequently the arithmetic carry from cmp survives until it is inserted as the next quotient bit. The loop has seven instructions, one of them conditional, and no data-dependent branch. Its sole branch is the backwards loop branch, taken 31 times. It uses no separate quotient processor register, zero processor register, temporary comparison processor register or saved arithmetic carry processor register. A Thumb instruction set rendering using conditional execution would need an explicit conditional-execution encoding such as it cs; that is an additional encoded instruction, not an unexplained free operation.The packed restoring division loop invariant relates it to the displayed algorithm. Specifically, let , let retain its original mathematical value, and let be the number of completed iterations. Define the processed prefix , its quotient and remainder . The processor register loop invariant isThe two terms in the low machine word occupy disjoint bit positions. Its next outgoing arithmetic carry is therefore the next original dividend bit, not a quotient bit.
adds shifts the low machine word; adcs doubles the high remainder and incorporates that dividend bit. cmp decides whether this trial remainder is at least the divisor; subcs performs the conditional subtraction, and adc appends its decision to the shifted quotient. This is exactly the doubling, compare/subtract and quotient-bit update, with the counter maintained separately. Before processing bit , the trial remainder is at most , so the high-word addition does not require a hidden 33rd remainder bit for this 32-bit dividend problem. After 32 iterations the residual dividend portion is zero, giving the stated outputs.There is a printed source error in the auxiliary bound. At the initial state, choosing valid inputs makes the printed strict inequality false. The algorithm instead preserves for its unpacked 64-bit variable, together with its printed equality loop invariant. Doubling and subtracting when necessary preserves that corrected bound. At termination the equality becomes ; since is then divisible by , it gives . This source error does not invalidate the algorithm or the packed implementation. The figure is mathematical pseudocode: its
2^32 denotes exponentiation, rather than C's XOR operator.The displayed A32 routine assembled successfully with Clang and was disassembled to check the conditional and non-flag-setting forms. Its carry flag model was checked exhaustively at an eight-bit machine word size and against boundary and randomized 32-bit divisions. No native ARM architecture family execution is claimed.
More processor registers can reduce register spills and the associated loads and stores. A richer instruction set may also replace several old machine instructions by one new operation. Both effects can decrease the number of instructions in a compiled program, although a particular program might obtain no benefit.
Wider instruction encodings increase the bytes per instruction. Consequently the total machine-code size can increase or decrease: approximately, it is instruction count times average encoded instruction width, with alignment and padding also relevant. There is no universal net direction without the program and revised encoding. The length of assembly language source text is a separate matter and is not determined by instruction bit widths.
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 overwrittenAfter 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]Thumb 16-bit instruction set quick reference by Arm. Load: signed halfword; Add/Subtract; Branch
Keep
total in the callee-saved register r4, and the first returned sum in the callee-saved register r5. Suppose the surrounding function has made an aligned stack frame with the local seven-halfword array at the current sp, occupying fourteen bytes in a sixteen-byte slot. One possible frame setup is push {r4,r5,r6,lr} followed by sub sp,sp,#16; the earlier code initializes total, regular, and special before this fragment. ldr r0, =regular @ assembler literal load of the global array address
movs r1, #7
bl sum16
movs r5, r0 @ first sum must survive the next call
add r0, sp, #0 @ current frame's local special array
movs r1, #7
bl sum16
muls r0, r5, r0 @ second sum times first sum
adds r4, r4, r0 @ update totalThe AAPCS32 permits each call to overwrite
r0–r3, r12, and condition flags, but requires preservation of r4–r8, r10, r11, and sp. Thus both r4 and r5 remain valid even if sum16 is replaced by another conforming implementation. bl changes the link processor register lr, so the enclosing function saves its own return address in its prologue. Its epilogue can use add sp,sp,#16 and pop {r4,r5,r6,pc}. The frame uses thirty-two bytes in total, preserving the required eight-byte stack pointer alignment at both calls.[ref]The two calls may be evaluated in this order. Assume the product and final addition fit the signed 32-bit result expected by the source program; unlike each individual seven-element sum, their product need not fit. The assembly language operations retain their low 32 bits if this assumption fails, whereas signed integer overflow in the C programming language has different semantics.
Let be the number of nonempty nodes and the maximum number on a root-to-leaf path. Both listings take time on a unit-cost machine: each node is visited once and its three fields are read once. The recursive listing executes two child calls per nonempty node, including calls on empty children; there are invocations in total. It saves and restores four words for every nonempty invocation. The iterative listing has one function frame, no recursive calls, and one push/pop pair per deferred nonempty right subtree. Thus it removes repeated call/return and frame-transfer overhead, although its extra loop tests also cost instructions. Exact cycle comparisons need a specified processor, memory timing and compiler; an optimizing compiler may alter either implementation.
For these particular assembly language listings, the recursive call stack uses bytes above the caller's frame; empty calls allocate no additional frame. The iterative listing uses a fixed bytes, even for a shallow or empty tree. With , the recursive maximum is 512 bytes, versus 144 bytes for this fixed-array iteration. If the promised depth of 32 instead counts edges, the recursive bound is bytes; the same 32-word pending array still suffices. Conversely, for recursion uses at most 128 bytes and is smaller than the fixed array. When sized dynamically to depth, both approaches use auxiliary storage, but their stored information differs: full suspended invocation state versus pending subtree roots. Therefore recursion is not intrinsically always slower or larger; the claim depends on generated code, tree shape and the choice to reserve a maximum-size explicit array.
Register-offset addressing 2026-10-24
An assembly language memory operand whose effective address is the sum of a base processor register and an offset processor register. A byte-load table lookup uses the index directly as a byte offset; wider entries require an appropriate scale. The effective address is formed from the old register values before the destination register is overwritten.