The SUB (subtract) instruction is a fundamental arithmetic operation in assembly language that computes the difference between two operands and stores the result. Like other assembly instructions, the precise syntax and behavior of SUB can vary between different processor architectures, such as x86, ARM, and MIPS, but its core function remains consistent.
Core mechanics
At its most basic, the SUB instruction performs the following action:
Destination = Destination - Source
The key components of this operation are:
- Destination operand: This is the register or memory location that holds the minuend (the number being subtracted from). After the instruction executes, the destination stores the final result.
- Source operand: This is the register, memory location, or immediate value that holds the subtrahend (the number to subtract). The source operand's value is not changed by the instruction.
- Flags: After executing
SUB, the CPU's status or flags register is updated to reflect the characteristics of the result. Important flags include:- Zero Flag (ZF): Set to 1 if the result is zero; otherwise, it is 0.
- Carry Flag (CF): In subtraction, this is often called the "borrow flag." It is set if a borrow was needed during the operation.
- Overflow Flag (OF): Set to 1 if the signed result is too large or too small to fit in the destination operand; otherwise, it is 0.
- Sign Flag (SF): Set to 1 if the signed result is negative; otherwise, it is 0.
Architectural variations
The general principle of the SUB instruction is universal, but different instruction set architectures (ISAs) have their own specific implementations.
x86 architecture (Intel, AMD)
In the x86 family of processors, the SUB instruction is very flexible, supporting various combinations of operands.
- Syntax:
SUB destination, source - Examples:
SUB AX, BX: Subtracts the 16-bit value in registerBXfrom the 16-bit value in registerAX. The result is stored inAX.SUB EAX, 10: Subtracts the immediate value 10 from the 32-bitEAXregister. The result is stored inEAX.SUB [my_variable], EBX: Subtracts the value inEBXfrom the value stored in the memory locationmy_variable.
ARM architecture
ARM processors have specific versions of the subtract instruction, depending on the number of operands and whether condition flags are updated.
- Syntax:
SUB{S} {<cond>} {<Rd>}, <Rn>, <Operand2>S: An optional suffix to indicate that the condition flags should be updated.<Rd>: The destination register.<Rn>: The first source register.<Operand2>: A flexible second operand, which can be a register, an immediate value, or a shifted register.
- Example:
SUBS R0, R1, R2- Subtracts the value in
R2from the value inR1. - Stores the result in
R0. - Sets the condition flags based on the result because the
Ssuffix is used.
- Subtracts the value in
ARM also has a RSB (Reverse Subtract) instruction, which performs the operation Destination = Source - Register, useful for certain operations.
MIPS architecture
In MIPS, the subtraction instruction has a more rigid three-operand format.
- Syntax:
sub rd, rs, rtrd: The destination register.rs: The first source register (minuend).rt: The second source register (subtrahend).
- Example:
sub $t0, $t1, $t2- Subtracts the value in register
$t2from the value in register$t1. - Stores the result in register
$t0.
- Subtracts the value in register
The role of two's complement arithmetic
A crucial detail of the SUB instruction is its reliance on two's complement representation to handle signed numbers. Modern CPUs don't have separate circuitry for addition and subtraction. Instead, subtraction is implemented as an addition operation using two's complement arithmetic: A - B is calculated as A + (-B). The CPU calculates -B by inverting all the bits of B and then adding 1.
Example: Subtracting 5 from 10 (decimal).
- Binary representation:
10is00001010and5is00000101. - Two's complement of 5:
- Invert bits of
00000101to get11111010. - Add 1 to get
11111011. This is the binary representation of -5.
- Invert bits of
- Perform addition:
00001010+11111011=00000101(with a carry ignored). - Result: The final answer is
00000101, which is 5 in decimal.
SUB vs. SBB (Subtract with Borrow)
In addition to the standard SUB instruction, many architectures provide a SBB (subtract with borrow) instruction. This instruction is used for performing multi-precision subtraction, where a number is larger than a single CPU register (e.g., 64-bit subtraction on a 32-bit machine).
SUBhandles the least significant part of the number.SBBthen subtracts the source operand and the value of the carry flag (borrow) from the destination operand for subsequent, more significant parts of the number.
Summary
The SUB instruction is a cornerstone of assembly language, enabling direct control over a processor's most fundamental arithmetic functions. Its function is to subtract a source operand from a destination operand, with precise behavior and syntax determined by the specific CPU architecture. The instruction updates condition flags to enable complex conditional logic and leverages two's complement arithmetic to handle signed integer operations efficiently.