Compare String Instructions 

The compare string instructions are used to compare two strings. They have one of the following forms:

CMPS dest_string, src_string
CMPSB
CMPSW
CMPSD

When the first form, CMPS des_string, src_string, is used the assembler will replace it by CMPSB, CMPSW, or CMPSD depending on the size of the operands dest_string and src_string.

The semantics of the instructions CMPSB, CMPSW, and CMPSD are illustrated below:

InstructionDescription
CMPSB Affect the flags based on the result of DS:[SI]-ES:[DI] ;
IF (DF=0)
{SI=SI+1; DI=DI+1}
ELSE
{SI=SI-1;DI=DI-1}
CMPSW Affect the flags based on the result of DS:[SI+1:SI]-ES:[DI+1:DI] ;
IF (DF=0)
{SI=SI+2; DI=DI+2}
ELSE
{SI=SI-2;DI=DI-2}
CMPSD Affect the flags based on the result of DS:[SI+3:SI]-ES:[D3+1:DI] ;
IF (DF=0)
{SI=SI+4; DI=DI+4}
ELSE
{SI=SI-4;DI=DI-4}

Note that unlike the CMP instruction which performs the operation destination - source, the compare string instructions perform the operation source - destination.

The CMPSB Instruction

This instruction is used to compare arrays of bytes. It compares the byte addressed by DS:[SI] to the byte addressed by ES:[DI] by performing the subtraction operation DS:[SI] - ES:[DI], setting the arithmetic flags based on the result of the subtraction. Note that the result is not stored and is just used to affect the flags. Then, SI and DI are either incremented or decremented by 1 depending on the Direction Flag. After executing this instruction, it is possible to use any of the conditional jump instructions.

The CMPSW Instruction

This instruction is used to compare arrays of words. It compares the word addressed by DS:[SI] to the word addressed by ES:[DI] by performing the subtraction operation DS:[SI+1:SI] - ES:[DI+1:DI], setting the arithmetic flags based on the result of the subtraction. Then, SI and DI are either incremented or decremented by 2 depending on the Direction Flag.

The CMPSD Instruction

This instruction is used to compare arrays of double words. It compares the double word addressed by DS:[SI] to the double word addressed by ES:[DI] by performing the subtraction operation DS:[SI+3:SI] - ES:[DI+3:DI], setting the arithmetic flags based on the result of the subtraction. Then, SI and DI are either incremented or decremented by 4 depending on the Direction Flag.

In the next example, we illustrate the use of compare string instructions in comparing two strings.

Example: Comparison of two strings.
	
	MOV	SI, offset str1
	MOV	DI, offset str2
	PUSH DS
	POP ES
	CLD			;left to right or auto-increment mode 
	MOV	CX, 12		;string length
Next:	CMPSB  			;cmp till equal or cx=0
	JB	str1smaller
	JA	str2smaller
	;the strings are equal - so far
	LOOP Next
	...

REPE/REPZ Prefix

Like the unconditional repeat prefix, there are conditional repeat prefixes that come with string instructions. REPE (Repeat if Equal) or REPZ (Repeat if ZF=1) is one of the conditional repeat prefixes that come with string instructions. Its operation is similar to the REP prefix except that repetition is also conditional on the Zero Flag as shown below:
	While (CX <> 0)
		execute the string instruction
		CX = CX - 1;
		If (ZF = 0) then
			exit loop
		end if
	end while

The string instruction will repeat execution as long as CX is not equal to 0 and also the result of comparison sets the ZF to 1, i.e. the two compared operands are equal. So, it will stop once the first mismatch is found or if CX becomes 0.

In the next example, we show the use of the REPE prefix in comparing two strings.

Example: Comparison of two strings using REPE prefix.
	
	MOV	SI, offset str1
	MOV	DI, offset str2
	PUSH DS
	POP ES
	CLD			;left to right or auto-increment mode 
	MOV	CX, 12		;string length
REPE   CMPSB  			;cmp till equal or cx=0
	JB	str1smaller
	JA	str2smaller
	;the strings are equal - so far
	...

REPNE/REPNZ Prefix

REPNE (Repeat if not Equal) or REPNZ (Repeat if ZF=0) is the second conditional repeat prefix. Its operation is as follows:
	While (CX <> 0)
		execute the string instruction
		CX = CX - 1;
		If (ZF = 1) then
			exit loop
		end if
	end while

The string instruction will repeat execution as long as CX is not equal to 0 and also the result of comparison sets the ZF to 0, i.e. the two compared operands are not equal. So, it will stop once the first match is found or if CX becomes 0.

For example, suppose that we want to count the number of characters that are matching between two strings. This can be done as follows:

Example: Counting number of character matches between two strings.
	
	MOV	SI, offset str1
	MOV	DI, offset str2
	PUSH DS
	POP ES
	CLD			;left to right or auto-increment mode 
	MOV	CX, 12		;string length
	XOR AL, AL		;# of character matches
Again:	JCXZ Done
REPNE  CMPSB  			;cmp till equal or cx=0
	JNE	Done
	INC	AL
	JMP Again
Done:
	...

Note that it is not allowed to use the REP prefix with the compare string instructions as it does not make sense. Similarly, it is not allowed to use the REPE/REPZ or REPNE/REPNZ prefixes with the move string instructions.