MOV (x86 instruction)

From Riff Wiki
Jump to: navigation, search

In the x86 assembly language, the MOV instruction is a mnemonic for the copying of data from one location to another. The x86 assembly language has a number of different move instructions. Depending on whether the program is in a 16-bit or 32-bit code segment (in protected mode) and whether an override instruction prefix is used, a MOV instruction may transfer 8-bits, 16-bits, or 32-bits of data (or 64-bits in x86-64 mode). Data may be copied to and from memory and registers.[1]

The word move for this operation is a misnomer: it has little to do with the physical concept of moving an object from A to B, with place A then becoming empty; a MOV instead makes a copy of the state of the object at A and overwrites the old state of B in this process. This is reflected in some other assembly languages by using words like load, store or copy instead of move.

Usage

The following is an example of Intel syntax, which copies the value in register y into register x:

MOV X, Y

This operation is represented by the following pseudocode:

X := Y

While MOV X, Y is equivalent to X := Y, the reverse is often not true, especially in high-level programming languages where X := Y will translate into more complex assembly language.

In AT&T assembler syntax, the above operation would be accomplished as follows:

mov %Y, %X

X and Y may be immediate values, registers, or memory references. Instruction suffixes are not necessary with AT&T syntax except in the case of immediate data to memory. Some possible suffixes are movb (byte, 8 bits), movw (word, 16 bits), movl (long, 32 bits), and movq (quad, 64 bits).

Either X or Y can include addressing information.

The operands for the MOV commands can either be registers, a segment register or a memory address since the command is executed in a single CPU work cycle. There is a succession as in:

move the contents of the register bx into the register ax

MOV ax, bx

move the contents of the register ax into the referenced memory block

MOV [address], ax

Memory to memory moves, such as

MOV [address1], [address2]

are not possible. To achieve this, MOV must be used in sequence:

MOV ax, [address2]
MOV [address1], ax

Usually, there is one set of opcodes for

MOV register, [address]
MOV [address], register

There are also special MOV opcodes for accessing control registers:

MOV ax,CR0 
MOV CR0,ax

(Same for other control registers, test registers, and debug registers.)

Zero extend

The instructions MOVSX (move with sign extend) and MOVZX (move with zero extend) can be used to copy data of different sizes. To move the higher byte of the 16-bit register BX sign-extended into the 32-bit register EAX, use:

MOVSX EAX,BH

Another example, that moves the value of AL into EAX, padding it with zeros:

MOVZX EAX,AL

For example, if AL were 0x2F, EAX would be set to 0x0000002F.

However, to zero-extend a 32-bit value to a 64-bit value when running in 64-bit mode, only a regular 32-bit MOV is required, since 32-bit values are always zero-extended in 64-bit mode. If RBX contains the value 0x0123456789ABCDEF, after:

 MOV EAX,EBX

register RAX will contain 0x0000000089ABCDEF.

Flag

These instructions don't affect flag registers.[2] That is, flags (such as CF/ZF etc.) keep their values before and after CPU executes a MOV instruction.

References

If these are not easily readable, you may have to view the page source to see them for the time being.

  1. {{#invoke:citation/CS1|citation |CitationClass=web }}
  2. {{#invoke:citation/CS1|citation |CitationClass=web }}