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 bit | src bit | result |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
1011 0110 AL = B6hAND 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).
MOV AL, 0B6h ; 1011 0110CALL SHOWBINAND AL, 0Fh ; keep bits 0..3CALL SHOWBIN ; 0000 0110MOV AL, "q"AND AL, 0DFh ; clear bit 5: "Q"MOV DL, ALMOV AH, 02hINT 21hSHOWBIN PROC NEAR ; print AL as 8 binary digits and a spacePUSHF ; keep the caller's flagsPUSH AXPUSH BXPUSH CXPUSH DXMOV BL, ALMOV CX, 8NEXTBIT:SHL BL, 1 ; the top bit falls into CFMOV DL, "0"ADC DL, 0 ; "0" + CF = "0" or "1"MOV AH, 02hINT 21hLOOP NEXTBITMOV DL, " "MOV AH, 02hINT 21hPOP DXPOP CXPOP BXPOP AXPOPFRETSHOWBIN ENDP