SBC (SuBtract with Carry)¶
A = A - [operand] - (1 - C)
or
A = A + ([operand] XOR 255) + C
SBC performs subtraction on the accumulator register (A), an operand, and the complement of the Carry flag. The result is truncated to 8 bits, and then stored in the accumulator.
The Carry flag is set if the unsigned result exceeds $FF (255), otherwise it is cleared. For subtracting two unsigned numbers, this is equivalent to the Carry flag being set if the result is non-negative.
There is no way to perform subtraction without including the Carry flag. Therefore, the Carry flag is typically set (with SEC) before a subtraction, unless a multi-byte subtraction is being performed.
If the Decimal flag is set, the SBC instruction assumes that the values being subtracted are in Binary Coded Decimal (BCD) format.
Addressing Modes¶
Mode |
Syntax |
Bytes |
Cycles |
---|---|---|---|
+SBC #const |
|
2 |
|
SBC #const |
|
2 |
|
SBC zp |
|
3 |
|
SBC zp,x |
|
4 |
|
SBC addr |
|
4 |
|
SBC addr,x |
|
4-5 |
|
Absolute+Y |
SBC addr,y |
|
4-5 |
SBC (zp,x) |
|
6 |
|
SBC (zp),y |
|
5-6 |
Flags Affected¶
N (Negative) – Set if the result of the subtraction has the most significant bit set (i.e., is negative); otherwise, it is cleared.
Z (Zero) – Set if the result of the subtraction is zero; otherwise, it is cleared.
C (Carry) – Set if the unsigned result of the (two’s complement) subtraction is not negative; otherwise, it is cleared.
V (Overflow) – Set if the two values being subtracted have opposite signs and the result has the sign of the second value; otherwise, it is cleared.
The Carry Flag¶
The subtraction operation performed using two’s complement arithmetic by taking the two’s complement of the operand and adding it to the accumulator. This can be simplified to an XOR operation with 0xFF (255 in decimal) to get the one’s complement of the operand, followed by an addition of the carry flag (to get the two’s complement):
After the SBC operation, the carry flag is set if there was no borrow during the subtraction (i.e., if the result is not negative), and it is cleared otherwise. In the 6502’s SBC instruction, the Carry flag serves a different purpose than in other arithmetic operations. In SBC, the Carry flag is used to indicate a “borrow” or “negative carry” during the subtraction operation.
When performing a subtraction, the Carry flag is typically set (with SEC) to indicate that the operation should subtract one more from the result than it normally would. This allows for the proper handling of situations where the subtracted value is larger than the minuend.
For example, consider subtracting the value 3 from 2. To perform this subtraction using the 6502’s SBC instruction, the two values would be loaded into the accumulator and the operand, respectively. The Carry flag would then be set before the subtraction:
LDA #2 ; load the minuend (2) into the accumulator
SEC ; set the carry flag
SBC #3 ; subtract the subtrahend (3) from the accumulator
The result of this operation is 255, which represents -1 in 2’s complement form. The Carry flag is set to 0, indicating a negative carry. If the Carry flag had been cleared before the subtraction, the result would have been 4, which is not the correct result for this operation.
It’s important to note that the Carry flag is only set when a negative carry occurs. If the result of the subtraction is non-negative, the Carry flag is cleared. In addition, the Overflow flag (V) may also be set if the result of the subtraction is too large to fit in 8 bits, or if a negative carry occurs due to the operands having different signs.
Examples¶
Simple Subtraction from a Constant
LDA #10 ; load A with constant 10
SEC ; set carry flag
SBC #1 ; A now contains 9
This performs a simple subtraction of a constant value from the accumulator register (A). Here is a step-by-step breakdown of the code:
LDA #10 – This loads the constant value 10 into the accumulator register.
SEC – This sets the carry flag to indicate that a borrow may be needed in the subtraction operation.
SBC #1 – This subtracts the constant value 1 from the value already in the accumulator. Since the carry flag was set in the previous step, the subtraction will take into account the borrow. As a result, the accumulator now contains the value 9.
Therefore, this code performs a simple subtraction of the constant value 1 from the constant value 10, and stores the result (9) in the accumulator register.