SBC (short for "SuBtract with Carry") is the mnemonic for a machine language instruction which subtracts the byte held at the specified memory address, from the one currently held in the accumulator, leaving the result in the accumulator: The state of the carry flag before the subtraction takes place, is taken as an incoming "borrow" flag in the computation. After the subtraction, the carry flag will indicate where a new "borrow" was "left over". Contrary to many other CPUs, the architecture of the 65xx family (of which the 6510 in the Commodore 64 is a member) does not have separate instructions for subtraction with or without taking the carry flag as the incoming "borrow" flag. Therefore the programmer must make sure that carry is set prior to a subtraction for which there is no incoming borrow to consider – this is usually accomplished with the SEC instruction, for example:
LDA Num1 Read the first byte value from Num1 SEC No incoming borrow; make sure carry is set SBC Num2 Perform the subtraction STA Result Store result in Result
This example takes the byte stored in a memory address labelled
Num2, and subtracts it from the contents of a memory address labelled
Num1, and stores the resulting difference in a third place with the label
In a few special cases (such as immediately following a BCC), the carry is always set in any situation where the CPU reaches the SBC instruction; this allows for leaving out the SEC, saving 1 byte and 2 machine cycles execution time.
The inclusion of the incoming borrow provides a simple means to subtract binary integers of arbitrary length, "spread" across two or more bytes: Subtract the least significant byte pair first with the carry flag set, then do the subtraction for increasingly significant bytes without modifying the carry prior to each; this will let the outgoing borrow from one subtraction "travel" from one byte to the next. The following example assumes that
Num2 mark the first of two series of bytes, of increasing significance, each holding a "dozens-of-bits" integer, and stores the resulting difference as a series of byte in the same order, beginning at label
LDA Num1 Subtract least SEC significant pair SBC Num2 with the carry STA Result set (= no borrow) LDA Num1+1 Subtract next SBC Num2+1 pair without STA Result+1 changing carry LDA Num1+2 and the next SBC Num2+2 pair... STA Result+2 ... etc.
SBC handles both signed and unsigned integers: Both examples above will yield correct results for any pair of integer where both the integers and the resulting difference are within the limits imposed by the number of bits involved: The single-byte addition example works for unsigned integers in the range 0–255/$0–FF as well as signed integers in the −128–+127/$−80–+7F range. For 16-bit (2 bytes) unsigned integers, the limits are 0–65535/$0–FFFF; for signed 16-bit quantities, it's −32768–+32767/$−8000–+7FFF, etc.
SBC supports eight different addressing modes, as shown in the table at right.
In the assembler formats listed, nn represents a single-byte (8-bit) figure, and nnnn is a two-byte (16-bit) address.
With some addressing forms (marked with an asterisk, *, in the "Number of cycles" column) the execution time for SBC depends on the circumstances: In cases where the indexing requires the CPU to "reach across" a page boundary from the base address, the execution time is 1 cycle longer than listed here.
SBC affects 4 of the CPU's status flags:
- The negative status flag is set if the result is negative, i.e. has it's most significant bit set.
- The overflow status flag is set if the operation results in an overflow.
- The zero flag is set if the result is zero, or cleared if it is non-zero.
- The carry flag is set or cleared depending on the result.