Move String Instructions 

The move string instructions are used to copy an array from one location to another location. They have one of the following forms:

MOVS dest_string, src_string
MOVSB
MOVSW
MOVSD

When the first form, MOVS des_string, src_string, is used the assembler will replace it by MOVSB, MOVSW, or MOVSD depending on the size of the operands dest_string and src_string.

The semantics of the instructions MOVSB, MOVSW, and MOVSD are illustrated below:

InstructionDescription
MOVSB ES:[DI]<-DS[SI] ;
IF (DF=0)
{SI=SI+1; DI=DI+1}
ELSE
{SI=SI-1;DI=DI-1}
MOVSW ES:[DI+1:DI]<-DS[SI+1:SI] ;
IF (DF=0)
{SI=SI+2; DI=DI+2}
ELSE
{SI=SI-2;DI=DI-2}
MOVSD ES:[DI+3:DI]<-DS[SI+3:SI] ;
IF (DF=0)
{SI=SI+4; DI=DI+4}
ELSE
{SI=SI-4;DI=DI-4}

The MOVSB instruction

The MOVSB (move string, byte) instruction fetches the byte at address SI, stores it at address DI and then increments or decrements the SI and DI registers by one.

The MOVSW instruction

The MOVSW (move string, word) instruction fetches the word at address SI, stores it at address DI and then increments or decrements SI and DI by two.

The MOVSD instruction

The MOVSD (move string, double word) instruction fetches the double word at address SI, stores it at address DI and then increments or decrements SI and DI by four.

Let us consider the case of moving (i.e. copying) an array Array1 from one location to another location Array2, assuming the number of elements to move is 100 bytes.

If we use the normal MOV instructions, the program would look like:

Example: Copy 100 bytes from Array1 to Array2, using the MOV instruction.
	LEA DI, Array2 	; Starting address of Destination 
	LEA SI, Array1		; Starting address of Source
	MOV CX, 100		; Number of elements = 100
Next:	MOV AL, [SI]		; AL   <== [SI]
	MOV [DI], AL		; [DI] <== AL
	INC SI			; SI + 1
	INC DI			; DI + 1
	LOOP Next		; Next element
	...

However, If the string instructions are used, the code would be:

Example: Copy 100 bytes from Array1 to Array2, using MOVSB instruction.
	
	LEA DI, Array2 	; Starting address of Destination
	LEA SI, Array1		; Starting address of Source
	MOV CX, 100		; Number of elements = 100
	PUSH DS
	POP ES			; make ES=DS
	CLD			; set SI and DI to auto-increment	
next:	MOVSB
	LOOP next

REP Prefix

Since string instructions are designed to operate on arrays of bytes, words, or double words, their execution is repeated depending on the size of the processed arrays. Instead of using the Loop instruction, the string instructions come with a repeat prefix, REP, that allows their execution to be repeated a number of times depending on the unsigned content of the CX register. The semantics of REP are:

	While (CX <> 0)
		execute the string instruction
		CX = CX -1
	end while

The CX register is first checked and if it is not 0, only then is the string instruction is executed. Thus, if CX is 0 to start with, the string instruction is not executed at all. This is in contrast to the LOOP instruction, which first decrements CX and then tests if CX is 0.

Next we show how the above example can be used with the REP prefix.

Example: Copy 100 bytes from Array1 to Array2, using MOVSB instruction with the REP prefix.
	
	LEA DI, Array2 	; Starting address of Destination 
	LEA SI, Array1		; Starting address of Source 
	MOV CX, 100		; Number of elements = 100 
	PUSH DS
	POP ES			; make ES=DS
	CLD			; set SI and DI to auto-increment	
REP	MOVSB

Note that Array1 can also be copied to Array2 using the MOVSW instruction. This is illustrated in the example below.

Example: Copy 100 bytes from Array1 to Array2, using MOVSW instruction with the REP prefix.
	
	LEA DI, Array2 	; Starting address of Destination
	LEA SI, Array1		; Starting address of Source
	MOV CX, 50		; Number of elements = 50 words = 100 bytes 
	PUSH DS
	POP ES			; make ES=DS
	CLD			;set SI and DI to auto-increment	
REP	MOVSW

We can also copy Array1 into Array2 by starting the copying from the bottom of the arrays. This is called the auto-decrement mode since SI and DI will be decremented after the move operation. This is illustrated in the example below.

Example: Copy 100 bytes from Array1 to Array2, using MOVSB instruction with the REP prefix based on the auto-decrement mode.
	
	LEA DI, Array2+99 	; Ending address of Destination 
	LEA SI, Array1+99	; Ending address of Source 
	MOV CX, 100		; Number of elements = 100 bytes 
	PUSH DS
	POP ES			; make ES=DS
	STD			; set SI and DI to auto-decrement 	
REP	MOVSB

In the next example, we illustrate the use of move string instructions to copy Array1 into Array2 in reverse.

Example: Copy 100 bytes from Array1 to Array2 in reverse order.
	
	LEA DI, Array2+99	; Ending address of Destination 
	LEA SI, Array1		; Starting address of Source
	MOV CX, 100		; Number of elements = 100 bytes 
	PUSH DS
	POP ES			; make ES=DS
	CLD			; set SI and DI to auto-increment	
Next:	MOVSB
	SUB DI, 2		; adjust DI to pint at next address
	LOOP Next

Note that in the above example, SI and DI are both incremented after the data movement. However, what we want is to have SI incremented by one while DI is decremented by one. To achieve this, we decrement DI by 2 after the MOVSB instruction so that the net effect on DI is decrementing it by 1. For this reason, we can not use the REP prefix here and we have to use the loop instruction.