x86 Assembler using MASM32 Tutorial 10 - A String Compare Function to Compare Two Hard Coded Strings



Watch the video or follow the tutorial.



This, the 10th tutorial we will create a string comparison function that will take two separate string variables in memory and compare them to see if they are the same string. If they are then one output is displayed and if they are not then another one is. So, first of all open Visual MASM, if you haven't installed Visual MASM yet you can learn how to do it here. Once installed open it and learn create the default code template needed for all my tutorials here. This default code will be the starting point for most of our tutorials including this one. So, once all this is done you should be looking at the code window as seen below:



Scroll down to the .data section and add the following eight variables:

strString1 DB "123456789", 0
len1 Equ $ - strString1
strString2 DB "123456789", 0
len2 Equ $ - strString2
strCap1 DB "Comparison Successful", 0
strMsg1 DB "Congratulations the strings match", 0
strCap2 DB "Comparison Unsuccessful", 0
strMsg2 DB "Unlucky the strings don't match", 0

In the .code section after start: the following code should be added

; Compare len1 and len2 if the are different the strings don't match
Mov Eax, len1
Mov Ebx, len2
Cmp Eax, Ebx
Jnz strings_dont_match

; set Esi to memory address of strString1
; set Ecx (for Repz) to strString1 length including 0 string terminator
; set Edi to address of strString2
Mov Esi, Offset strString1
Mov Ecx, len1
Mov Edi, Offset strString2

; Repeat until the values in the memory of [EDI] and [ESI] are different, or Ecx = 0
Repz Cmpsb

; If Ecx = 0 then cmpsb command got to end of string
; If Ecx != 0 then cmpsb found bytes that didnt match
Jz strings_match
Jmp strings_dont_match

strings_match:

; Strings match MessageBox Congratulations
Push MB_OK
Push Offset strCap1
Push Offset strMsg1
Push 0
Call MessageBox
Jmp end_

strings_dont_match:

; Strings don't match MessagBox Error
Push MB_OK
Push Offset strCap2
Push Offset strMsg2
Push 0
Call MessageBox

end_:


The first section compares the values of len1 and len2 which are the lengths of the two strings, after a compare command between the two registers that contain len1 and len2 if they are different then the strings are not equal and there is no need to conduct the string comparison, the code jumps to the strings_dont_match label and an error message is displayed and the program ends. Next we load the memory address of the two strings into the Esi and Edi registers which are generally used during a Cmpsb command. Ecx is loaded with the value of len1 which tells us how many times we should conduct the comparison. Ecx will be reduced by one after each iteration, when it reaches zero the comparison function ends.

Repz Cmpsb means repeat until the zero flag indicates that the values in Esi and Edi are not equal and Cmpsb means compare strings byte by byte whereas for example Cmpsw means compare strings word by word which is compare every two byte values. After the Repz Cmpsb command a compare command is conducted between the value in Ecx and zero. If Ecx contains zero then the comparison functions compared all the values in the two strings and they were all equal. If it is not zero then the function found bytes that were not equal. A different Jump command is given for each outcome.

If the value in Ecx got to zero then a MessageBox reporting a successful comparison is shown otherwise an error is reported.

The entire code looks like this:

; *************************************************************************
; 32-bit Windows Program
; *************************************************************************

.686                                      ; Enable 80686+ instruction set
.model flat, stdcall                ; Flat, 32-bit memory model (not used in 64-bit)
option casemap: none         ; Case sensitive syntax

; *************************************************************************
; MASM32 proto types for Win32 functions and structures
; *************************************************************************
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\masm32rt.inc     ; for using ustr$() and such like

; *************************************************************************
; MASM32 object libraries
; *************************************************************************
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

; *************************************************************************
; Our data section.
; *************************************************************************
.data

strString1 DB "123456789", 0
len1 Equ $ - strString1
strString2 DB "123456789", 0
len2 Equ $ - strString2
strCap1 DB "Comparison Successful", 0
strMsg1 DB "Congratulations the strings match", 0
strCap2 DB "Comparison Unsuccessful", 0
strMsg2 DB "Unlucky the strings don't match", 0

; *************************************************************************
; Our unintialised data section.
; *************************************************************************
.data?


; *************************************************************************
; Our constant section.
; *************************************************************************
.const



; *************************************************************************
; Macros
; *************************************************************************



; *************************************************************************
; Our executable assembly code starts here in the .code section
; *************************************************************************
.code

start:

    ; Compare len1 and len2 if the are different the strings don't match
    Mov Eax, len1
    Mov Ebx, len2
    Cmp Eax, Ebx
    Jnz strings_dont_match

    ; set Esi to memory address of strString1
    ; set Ecx (for Repz) to strString1 length including 0 string terminator
    ; set Edi to address of strString2
    Mov Esi, Offset strString1
    Mov Ecx, len1
    Mov Edi, Offset strString2

    ; Repeat until the values in the memory of [EDI] and [ESI] are different, or Ecx = 0
    Repz Cmpsb

    ; If Ecx = 0 then cmpsb command got to end of string
    ; If Ecx != 0 then cmpsb found bytes that didnt match
    Jz strings_match
    Jmp strings_dont_match

strings_match:

    ; Strings match MessageBox Congratulations
    Push MB_OK
    Push Offset strCap1
    Push Offset strMsg1
    Push 0
    Call MessageBox
    Jmp end_

strings_dont_match:

    ; Strings don't match MessagBox Error
    Push MB_OK
    Push Offset strCap2
    Push Offset strMsg2
    Push 0
    Call MessageBox

end_:

    Push 0
    Call ExitProcess

end start


Run the program as many times as you like changing the values of the two strings to see what happens.

Thank you for following this tutorial, I hope you found it useful. In the next tutorial we will have a look at comparing two strings and determining whether they match or not, so until then, enjoy.

Link to a text file with complete source code and more comments - here.