ADD adds the source operand to the destination and leaves the sum in the destination. Both operands have the same size: two bytes (ADD AL, BL) or two words (ADD AX, BX). The source can be a register, a memory operand or an immediate; the destination is a register or memory.

MOV AL, 25
MOV BL, 17
ADD AL, BL ; AL = 42
AAM ; AH = tens, AL = ones
OR AX, 3030h ; both digits -> characters
MOV BX, AX
MOV DL, BH
MOV AH, 02h ; DOS: print DL
INT 21h
MOV DL, BL
MOV AH, 02h
INT 21h

Forms

Any combination of register, memory and immediate works except two memory operands: ADD [A], [B] does not exist, so load one of them into a register first. Segment registers cannot take part, and an immediate cannot be the destination. There is a shorter encoding for ADD AL, imm and ADD AX, imm, and a word destination can take a small signed immediate (-128..127) in a single byte; the assembler picks these by itself. When the destination is memory and the source is an immediate, nothing tells the assembler the size, so write ADD WORD PTR [BX], 5 or ADD BYTE PTR [BX], 5.

Flags

The CPU does not know whether you mean the numbers as signed or unsigned, so it computes the flags for both readings at once. Pick the one that matches your data.

FlagSet when
CFthe unsigned sum did not fit: a carry out of the top bit
OFthe signed sum did not fit: two positives gave a negative, or two negatives a positive
SFthe top bit of the result is 1
ZFthe result is 0
AFa carry out of bit 3 (used by AAA and DAA)
PFthe low byte of the result has an even number of 1 bits

For example MOV AL, 200 then ADD AL, 100 gives AL = 44 with CF = 1 (300 does not fit in a byte), while MOV AL, 100 then ADD AL, 100 gives AL = 200 (C8h) with CF = 0 but OF = 1, because as signed bytes 100 + 100 = -56 is wrong.

Idioms

ADD AX, AX doubles a value, the same as a shift left by one. To add numbers wider than 16 bits, add the low words with ADD and the higher words with ADC, which also adds the carry from the step before.

Later CPUs

The 386 adds 32-bit forms such as ADD EAX, EBX. The 8086 forms work unchanged.