MOV dst, src copies the source operand into the destination; the source keeps its value. Both operands have the same size, two bytes or two words, and the assembler refuses a mix such as MOV AX, BL. The source may be a register, a memory location or an immediate number; the destination is a register or a memory location. Because nothing is calculated, MOV never changes a flag. That makes it safe to place between a CMP and the conditional jump that reads its result.
Forms
| Form | Example |
|---|---|
| reg, reg | MOV AX, BX |
| reg, mem / mem, reg | MOV CL, [SI] / MOV [VAR], DX |
| reg, imm | MOV AH, 09h |
| mem, imm | MOV BYTE PTR [BX], 0 |
| sreg, reg16/mem16 | MOV DS, AX |
| reg16/mem16, sreg | MOV AX, ES |
A move between AL or AX and a fixed address has its own shorter encoding; MASM picks it by itself.
MOV AX, 5 ; immediate -> registerMOV [N1], AX ; register -> memoryMOV BX, [N1] ; memory -> registerMOV CX, BX ; register -> registerMOV [N2], 3 ; immediate -> memory (N2 is a byte)ADD CL, [N2] ; 5 + 3MOV AL, CLADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hN1 DW 0N2 DB 0
Not allowed
There is no memory-to-memory move: MOV [A], [B] must go through a register. An immediate cannot go into a segment register, and one segment register cannot be copied into another; both go through a general register or the stack. CS is never a destination (only far jumps, calls and returns change it), and IP cannot be named at all. An immediate that does not fit the destination, such as MOV AL, 300, is an error.
MOV AX, 0B800h ; MOV ES, 0B800h does not existMOV ES, AXPUSH DS ; MOV ES, DS does not exist either:POP ES ; copy it through the stack
Pitfalls
In MASM, MOV AX, VAR reads the word stored at VAR. To get the address of VAR, write MOV AX, OFFSET VAR. When no register gives the size, as in MOV [BX], 5, add BYTE PTR or WORD PTR. After loading SS, load SP in the very next instruction: the 8086 holds off interrupts for one instruction after a segment register is loaded, so an interrupt cannot arrive between the two moves.
Later CPUs
The 80386 adds 32-bit registers (MOV EAX, EBX), the extending moves MOVZX and MOVSX, and moves to and from its control and debug registers. In protected mode (80286 and later) a move into a segment register also loads a descriptor and can fault.