XOR compares the two operands bit by bit and stores the result in the first. A result bit is 1 when the two bits differ and 0 when they are the same. With a mask, every 1 in the mask flips the matching bit and every 0 leaves it alone.

dst bitsrc bitresult
000
011
101
110

Forms and flags

Same operand rules as AND and OR: register or memory destination, register, memory or immediate source, equal sizes, no memory-to-memory, no segment registers. CF and OF are cleared, SF ZF PF describe the result, AF is undefined.

Idioms

XOR AX, AX is the usual way to zero a register. Every bit is the same as itself, so the result is 0; it is two bytes long where MOV AX, 0 takes three, and it also leaves ZF=1 and CF=0. The difference matters when you need the flags kept: MOV does not touch them, XOR does.

XOR undoes itself: applying the same mask twice gives back the original value. That is the idea behind toggling a bit each time a key is pressed, simple XOR "encryption", and drawing a cursor that disappears when drawn again. XOR AX, BX is zero exactly when AX equals BX, though CMP is the normal way to compare. XOR AL, 0FFh flips all bits like NOT, but unlike NOT it sets the flags.

You may meet the trick of swapping two registers with three XORs; on the 8086 XCHG does it in one instruction and is easier to read.

Prints 01011010 01010101 01011010 00000000
MOV AL, 5Ah ; 0101 1010
CALL SHOWBIN
XOR AL, 0Fh ; flip the low nibble
CALL SHOWBIN ; 0101 0101
XOR AL, 0Fh ; again: back to 5Ah
CALL SHOWBIN
XOR AL, AL ; zero, ZF = 1
CALL SHOWBIN
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