6.2 Arithmetic Instructions and Flags
Data-transfer instructions preserve a bit pattern. Arithmetic instructions instead calculate a new pattern and update status flags—single bits that summarize properties the CPU will need later. You met the FLAGS register in Chapter 4; here we connect each flag to concrete arithmetic.
ADD, SUB, INC, DEC, and NEG
ADD destination,source replaces the destination with their sum. SUB destination,source replaces it with destination minus source. The source remains unchanged.
INC operand adds 1, while DEC operand subtracts 1. They update OF, SF, ZF, AF, and PF but deliberately preserve CF. NEG operand computes zero minus the operand. Negating zero clears CF; negating any nonzero value sets CF.
For an 8-bit destination, only the low 8 result bits are stored. For example, FFH+01H=100H, but an 8-bit register stores 00H. The discarded ninth bit is remembered in CF.
The six arithmetic status flags are:
- CF, carry flag: an unsigned addition produced a bit beyond the destination, or an unsigned subtraction required a borrow.
- PF, parity flag: the low result byte contains an even number of 1 bits.
- AF, auxiliary carry flag: a carry or borrow crossed between bits 3 and 4; this supports decimal-adjust instructions.
- ZF, zero flag: every stored result bit is zero.
- SF, sign flag: the stored result’s highest bit is 1.
- OF, overflow flag: the signed result is outside the destination’s two’s-complement range.
CF and OF answer different questions
An 8-bit pattern can be interpreted as unsigned 0 through 255 or signed −128 through +127. The ALU does not choose one interpretation; it calculates once and provides both CF and OF.
Consider 7FH+01H=80H:
- Unsigned: 127+1=128 is representable, so CF=0.
- Signed: +127+1 cannot fit; stored
80Hmeans −128, so OF=1.
Now consider FFH+01H=00H:
- Unsigned: 255+1 needs a ninth bit, so CF=1.
- Signed: −1+1=0 is valid, so OF=0.
Never use CF alone to diagnose signed overflow, and never use OF alone to diagnose unsigned carry.
ADC and SBB extend arithmetic beyond one word
The 8086 ALU is 16 bits wide, but a program can represent a 32-bit integer as a high word and a low word. The low words are processed first:
ADD lowA,lowB
ADC highA,highBADC means add with carry: highA becomes highA+highB+CF. For subtraction, SBB means subtract with borrow: highA becomes highA−highB−CF.
Example: 0000FFFFH+00000001H. The low-word calculation FFFFH+0001H stores 0000H and sets CF. ADC 0000H,0000H includes that carry and produces high word 0001H, so the combined answer is 00010000H. Replacing ADC with ADD would incorrectly lose the bit crossing the word boundary.
Arithmetic can create useful masks, counters, and comparisons, but sometimes a program needs to modify individual bits without ordinary addition. Section 6.3 introduces logic, shifting, and rotation.