AND combines its two operands bit by bit and writes the result into the first one. A result bit is 1 only when the matching bit is 1 in both operands. Think of the second operand as a mask: where the mask has a 1 the bit survives, where it has a 0 the bit is forced to 0.

dst bitsrc bitresult
000
010
100
111
1011 0110 AL = B6h
AND 0000 1111 mask 0Fh
= 0000 0110 AL = 06h: only the low nibble is left

Forms

The destination is a register or a memory location; the source is a register, memory or an immediate value. Both must be the same size, byte or word. There is no memory-to-memory form (load one side into a register first), segment registers cannot be used, and an immediate cannot be the destination. With memory and an immediate, say the size: AND BYTE PTR [BX], 7Fh.

Flags

CF and OF are always cleared. SF, ZF and PF describe the result, so JZ right after an AND tells you that no masked bit was set. AF is undefined. If you only want the flags and need to keep the value, use TEST instead.

Idioms

Keep the low nibble before turning it into a digit: AND AL, 0Fh. Take the remainder of an unsigned division by a power of two: AND AX, 7 leaves AX mod 8. Round down to a multiple of 16: AND AX, 0FFF0h. Turn an ASCII lowercase letter into uppercase by clearing bit 5: AND AL, 0DFh (only for letters; other characters get changed too).

Prints 10110110 00000110 Q
MOV AL, 0B6h ; 1011 0110
CALL SHOWBIN
AND AL, 0Fh ; keep bits 0..3
CALL SHOWBIN ; 0000 0110
MOV AL, "q"
AND AL, 0DFh ; clear bit 5: "Q"
MOV DL, AL
MOV AH, 02h
INT 21h
SHOWBIN PROC NEAR ; print AL as 8 binary digits and a space
PUSHF ; keep the caller's flags
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BL, AL
MOV CX, 8
NEXTBIT:
SHL BL, 1 ; the top bit falls into CF
MOV DL, "0"
ADC DL, 0 ; "0" + CF = "0" or "1"
MOV AH, 02h
INT 21h
LOOP NEXTBIT
MOV DL, " "
MOV AH, 02h
INT 21h
POP DX
POP CX
POP BX
POP AX
POPF
RET
SHOWBIN ENDP