XCHG a, b puts the value of b into a and the old value of a into b in one instruction, without a third register. The operands are two bytes or two words. At least one of them is a general register; the other is a register or a memory location. The order of the operands does not matter: XCHG AL, [V1] and XCHG [V1], AL do the same thing. No flags change.
MOV AL, 4XCHG AL, [V1] ; AL = 9, V1 = 4ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hMOV AL, [V1]ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hV1 DB 9
Forms and limits
Exchanging AX with another 16-bit register has a one-byte encoding. The byte 90h is XCHG AX, AX, which does nothing: that is the NOP instruction. Segment registers cannot be exchanged, an immediate cannot take part (there is nowhere to put the old value), and two memory operands are not allowed.
Uses
XCHG AH, AL swaps the two bytes of AX, which turns a big-endian word into the little-endian order the 8086 uses, and back. Exchanging a register with memory is the basis of a lock: write 1 into a flag byte and get its old value in the same step. If the old value was 0, the lock is yours. On a system with more than one bus master, put LOCK in front so nobody can touch the byte between the read and the write.
SPIN1:MOV AL, 1LOCK XCHG AL, [FLAG1] ; take the lock; AL = its old valueCMP AL, 0JNE SPIN1 ; somebody else holds it: try again; ... the protected work ...MOV [FLAG1], 0 ; release
Pitfalls
The sizes must match: XCHG AX, BL is an error. Swapping two memory variables needs a register in the middle: load one, exchange it with the other, store it back. When you only want to copy, use MOV; an exchange with memory reads and writes the location and is slower.
Later CPUs
Later processors lock the bus for an exchange with memory even without the LOCK prefix. The 80486 adds BSWAP to reverse the bytes of a 32-bit register, plus XADD and CMPXCHG for lock-free counters and updates.