Signed Arithmetic
Signed Numbers and Negative Values
So far we have only worked with positive (unsigned) numbers. But real programs need to handle negative values too. ARM64 uses two's complement representation, the same system used by virtually every modern processor.
Two's Complement
In two's complement, the most significant bit (bit 63 for 64-bit registers) acts as the sign bit:
| Bit 63 | Meaning |
|---|---|
| 0 | Positive number (or zero) |
| 1 | Negative number |
To negate a value, you invert all bits and add 1. For example, in 8-bit:
5=00000101-5=11111011(invert:11111010, add 1:11111011)
The beauty of two's complement is that ADD and SUB work the same way for signed and unsigned values -- the hardware does not need separate circuits.
Negative numbers are like the Mirror Universe in Star Trek -- every positive value has an evil twin on the other side of zero, and two's complement is the portal between them.
NEG -- Negate
NEG computes the two's complement negation of a register:
MOV X0, #42
NEG X1, X0 // X1 = -42
This is equivalent to SUB X1, XZR, X0 (subtracting from zero).
SDIV -- Signed Division
We have used UDIV for unsigned division. SDIV performs signed division, which handles negative operands correctly:
// Unsigned division:
UDIV X2, X0, X1 // treats all bits as positive magnitude
// Signed division:
SDIV X2, X0, X1 // treats bit 63 as sign bit
For example, if X0 holds -15 and X1 holds 4:
SDIVgives -3 (rounds toward zero)UDIVwould interpret -15 as a huge positive number and give a wrong result
Signed vs Unsigned Comparisons
After CMP, different branch conditions handle signed vs unsigned:
| Signed | Unsigned | Meaning |
|---|---|---|
B.GT | B.HI | Greater than |
B.GE | B.HS | Greater than or equal |
B.LT | B.LO | Less than |
B.LE | B.LS | Less than or equal |
Computing Absolute Values
A common pattern with signed numbers is computing absolute values. If a subtraction produces a negative result, you negate it:
SUB X2, X0, X1 // X2 = a - b (might be negative)
CMP X2, #0
B.GE positive // if X2 >= 0 (signed), skip
NEG X2, X2 // X2 = -X2 (make positive)
positive:
Signed Remainder
ARM64 has no modulo instruction. To compute the signed remainder a % b, use the pattern:
SDIV X2, X0, X1 // X2 = a / b
MUL X3, X2, X1 // X3 = (a / b) * b
SUB X4, X0, X3 // X4 = a - (a / b) * b = a % b
Your Task
Given two values a = 12 and b = 37, compute the absolute difference |a - b|. Since a < b, subtracting a - b gives a negative result (-25). Negate it to get 25. Print the result followed by a newline.