Question

I have a 8086 Assembly Language Program to find out whether a given sub-string is present or not in a main string of characters. Its working fine when the sub string is a single character.Otherwise not. Help me to find the bug.

here is my code snippet

print macro arg                  
lea dx,arg
mov ah,09h
int 21h
endm

data segment

CarriageReturn equ 0dh      ; Next Line
LineFeed equ 0ah            ; Printer Next Line

Message1 db CarriageReturn,LineFeed,"Enter the string:$"
Message2 db CarriageReturn,LineFeed,"Enter the sub string:$"
Message3 db CarriageReturn,LineFeed,"sub string found $"
Message4 db CarriageReturn,LineFeed,"sub string not found $"
String db 100 dup(?)
SubString db 100 dup(?) 


outs dw 100 dup(?)
begin db 0000h
n db 0000h
StringLength db 0000h
SubStringLength db 0000h
dif db 0000h
n1 db 0000h
of1 dw 0000h
data ends 


code segment
assume cs:code,ds:data
start:  
    mov ax,data             ; Point ds ( Data Segement )
    mov ds,ax               ; To data segment          
    lea si,String           ; si to Main String 
    lea di,SubString        ; di to Sub String
    mov cl,00h
    print Message1          ; Call Macro to Display String "Enter the String" 

LoopReadMainString:
    mov ah,01h              ; Dos Function To Read Character From Standard Input
    int 21h                 ; Dos Interrupt 21h 
                            ; OUTPUT : AL = character from the standard input device
    cmp al,0dh              ; Cmp if carrage return or Enter Key is Pressed
    mov StringLength,cl     ; Store the Length of String in Memory
    je l1                   ; If Enter Key is pressed jump to l1 
    mov [si],al             ; Store Character in Memory Address of Main String 
    inc si                  ; Increment to Next Memory Location for next character in Main String
    inc cl                  ; Increment String Length Counter
    jmp LoopReadMainString

l1:
    print Message2          ; Call Macro to Display String "Enter the sub string"
    mov cl,00h
    jmp LoopReadSubString

LoopReadSubString:
    mov ah,01h              ; Dos Function To Read Character From Standard Input
    int 21h                 ; Dos Interrupt 21h     
    cmp al,0dh              ; Cmp if carrage return or Enter Key is Pressed
    mov SubStringLength,cl  ; Store the Length of Sub String in Memory
    je l3                   ; If Enter Key is pressed Jump to l3
    mov [di],al             ; Store Character in Memory Address of Sub Main String 
    inc di                  ; Increment to Next Memory Location for next character in Main String
    inc cl                  ; Increment String Length Counter
    jmp LoopReadSubString




l3:
    mov al,StringLength
    cmp al,SubStringLength  ; Cmp if StringLength = SubStringLength
    jz l4                   ; Jump to l4 if zero flag is set, ZF = 1 if equal  
    jnc l4                  ; Jump if carry flag not set to l4
    jc exit1                ; if carry flag is set go to exit

l4:
    lea si,String           ; Load effective address of string to si, ideally point si to memory location of String
    lea di,SubString        ; Point di to memory location of SubString
    mov bl,[di]             ; copy character in memory location of di ( SubString ) to bl
    mov begin,bl            ; copy character to begin variable
    mov cl,StringLength     ; cl or cx is generally used as counter, copy String Length to cl
    jmp l5                  ; Jmp to l5.   



l5:
    cmp cl,00h              ; cmp to see if the value of cl counter ie length of string  value is 0            
    je exit1                ; jump to exit. 
    mov al,[si]             ; copy character in main string to al
    cmp al,begin            ; Compare character in main string with character in substirng ( both are  pointing to memory location )
    mov bl,SubStringLength  ; bl will contain the string length of substring
    jz l8                   ; if they are same jump to l8
    inc si                  ; inc Main String Pointer to point to next character
    dec cl                  ; counter cx is decrease  to compare to zero the first line in l5 
    jmp l5                  ; loop . jump to l5

l8:
    dec cl           
    mov ax,si
    mov of1,ax
    jmp l6

l6:
    cmp bl,00h
    je exit2
    mov al,[si]
    cmp al,[di]
    inc si
    inc di
    dec bl
    jnz l7
    jmp l6

l7:
    mov si,of1
    mov al,[si]
    inc si
    lea di,SubString
    jmp l5



  exit1:
    print Message4              ; Print "Substring Found"
    mov ah,4ch                  ; Dos Sub Function To Exit Program
    int 21h                     ; Dos Interrupt 21h

  exit2:
    print Message3              ; Print "Substring Not Found"
    mov ah,4ch                  ; Dos SubFunction To Exit Program
    int 21h                     ; Dos Interrupt 21h
code ends
end start
Was it helpful?

Solution 5

print macro arg
lea dx,arg
mov ah,09h
int 21h
endm

data segment
CarriageReturn equ 0dh      ; Next Line
LineFeed equ 0ah            ; Printer Next Line

Message1 db CarriageReturn,LineFeed,"Enter the string:$"
Message2 db CarriageReturn,LineFeed,"Enter the sub string:$"
Message3 db CarriageReturn,LineFeed,"sub string found $"
Message4 db CarriageReturn,LineFeed,"sub string not found $"
String db 100 dup(?)
SubString db 100 dup(?) 


outs dw 100 dup(?)
begin db 0000h
n db 0000h
StringLength db 0000h
SubStringLength db 0000h
dif db 0000h
n1 db 0000h
of1 dw 0000h
 data ends 


 code segment
assume cs:code,ds:data
start:  
        mov ax,data             ; Point ds ( Data Segement )
    mov ds,ax               ; To data segment          
    lea si,String           ; si to Main String 
    lea di,SubString        ; di to Sub String
    mov cl,00h
    print Message1          ; Call Macro to Display String "Enter the String" 

     LoopReadMainString:
        mov ah,01h              ; Dos Function To Read Character From Standard Input
    int 21h                 ; Dos Interrupt 21h 
                            ; OUTPUT : AL = character from the standard i/0 devi       
    cmp al,0dh              ; Cmp if carrage return or Enter Key is Pressed
    mov StringLength,cl     ; Store the Length of String in Memory
    je Next                   ; If Enter Key is pressed jump to l1 
    mov [si],al             ; Store Character in Memory Address of Main String 
    inc si                  ; Increment to Next Memory Location for next                   character in Main String
    inc cl                  ; Increment String Length Counter
    jmp LoopReadMainString

   Next:
        print Message2          ; Call Macro to Display String "Enter the sub string"
    mov cl,00h
    jmp LoopReadSubString

        LoopReadSubString:
     mov ah,01h              ; Dos Function To Read Character From Standard Input
    int 21h                 ; Dos Interrupt 21h     
    cmp al,0dh              ; Cmp if carrage return or Enter Key is Pressed
    mov SubStringLength,cl  ; Store the Length of Sub String in Memory
    je Nextto                  ; If Enter Key is pressed Jump to l3
    mov [di],al             ; Store Character in Memory Address of Sub Main String 
    inc di                  ; Increment to Next Memory Location for next character in Main String
    inc cl                  ; Increment String Length Counter
    jmp LoopReadSubString




   Nextto:
        lea si,String
    lea di,SubString

         CheckFirstLetter:mov al,[si]
    mov bl,[di]
    cmp al,bl
    jne CheckNextLetter
    inc di
    dec SubStringLength
    jnz CheckNextLetter
    print Message3
    jmp exit

       CheckNextLetter:inc si
    dec StringLength
    mov dl,StringLength
    cmp dl,00h
    jnz checkit
    print Message4
  checkit:mov al,[si]
    mov bl,[di]
    cmp al,bl
    je CheckFirstLetter
    print Message4

   exit:

    mov ah,4ch                  ; Dos Sub Function To Exit Program
    int 21h                     ; Dos Interrupt 21h



      code ends
     end start

OTHER TIPS

org 100h

; add your code here

.data


string db 'umare  q$'

stringS dw 18

subString db 'umar'

subSize dw 4

count db 0


;########################################   .code

lea si , string

mov ax , ds

mov es , ax

lea di , subString


;#########################################


mov cx ,  stringS

cld

again:

lea di , subString

mov cx , subSize

repe cmpsb

je Equal

jmp ee


Equal:

inc count

ee:

cmp [ds+si] , '$'

jne again

;#########################################

.exit

ret

Rajil k.v try this code... i hope it is working... actually i just edited your own code... so i am not guarantee that it is 100% working... so please check and give your feedback

print macro arg    
lea dx,arg    
mov ah,09h    
int 21h    
endm

data segment

cr equ 0dh    
lf equ 0ah    
m1 db cr,lf,"Enter the string:$"    
m2 db cr,lf,"Enter the sub string:$"    
m3 db cr,lf,"sub string found $"    
m4 db cr,lf,"sub string not found $"    
str db 100 dup(?)    
rev db 100 dup(?)    
count1 db 0000h    
count2 db 0000h    

data ends

code segment

assume cs:code,ds:data

start:  mov ax,data        
mov ds,ax        
mov si,offset str        
mov di,offset rev        
mov cl,00h        
print m1

l0:mov ah,01h        
int 21h        
cmp al,0dh        
je l1        
mov [si],al        
inc si        
inc cl        
mov count1,cl       
jmp l0    

l1:print m2       
mov cl,00h

l2:mov ah,01h       
int 21h       
cmp al,0dh       
je l3       
mov [di],al       
inc di       
inc cl       
mov count2,cl        
jmp l2

l3:mov si,offset str       
mov di,offset rev 

lpag:mov al,[si]       
mov bl,[di]       
cmp al,bl       
jne lpne       
inc di      
dec count2       
jnz lpne       
print m3       
jmp lpend1

lpne: inc si          
dec count1          
mov dl,count1          
cmp dl,00h          
jnz lpag          
print m4

lpend1:mov ah,4ch        
int 21h

code ends

end start

Here is my code snippet to find if a (sub)String is present or not in a blockbuffer, as published at http://www.asmcommunity.net/forums/topic/?id=20464

  MOV EDI,OFFSET BlockBuffer 
  MOV ECX,SIZEOF BlockBuffer 
  MOV ESI,OFFSET String 
  MOV EDX,SIZEOF String - 1 
  CLD 
  LODSB ; 1st Char of String 
Find1stChar: 
  REPNE SCASB ; find 1st Char in BlockBuffer 
  JNE NotFound ; all BlockBuffer searched 
  PUSH ECX,ESI,EDI 
   CMP ECX,EDX 
   JB NearEnd 
   MOV ECX,EDX 
   REPE CMPSB ; compare the rest of String 
NearEnd: 
  POP EDI,ESI,ECX 
  JNE Find1stChar ; if not found, continue with 1st Char 
Found: DEC EDI ; to point at string in BlockBuffer

You can try my Code:

DATA SEGMENT
STR1 DB 'MADAM'
LEN1 DW ($-STR1);       storing the length of STR1
STR2 DB 'MADAA'
LEN2 DW ($-STR2);       stroing the length of STR2
DATA ENDS

CODE SEGMENT

LEA SI, STR1
LEA DI, STR2
MOV DX, LEN1
MOV CX, LEN2
CMP CX, DX;             comparing main & substring length
JA EXIT;                if substring size is bigger than there is no chance to be found it in main string
JE SAMELENGTH;          if main & sub string both have same length the we can compare them directly
JB FIND;                general case (substring length < mainstring length): we can apply our main process                 

SAMELENGTH:
        CLD
        REPE CMPSB
        JNE RED
        JMP GREEN

FIND:        
        MOV AL, [SI];   storing the ascii value of current character of mainstring 
        MOV AH, [DI];   storing the ascii value of current character of substring
        CMP AL,AH;      comparing both character
        JE CHECK;       
        JNE NOTEQL

NOTEQL:
        INC SI;         if both character don't match then we would point to the next char of main string
        DEC DX;         DX keeps track of how many character of mainstring is left to process
        CMP DX, 0000H;  checking if there are any character left in the main string for further comparison 
        JE RED;         if no character is left in main string then obviously the substring doesn't exists in main string
        JMP FIND

CHECK:
        MOV CX, LEN2;   CX is used internally for REPE CMPSB. So storing length of the substring in CX would limit the number of characters for comparison to exact length of substring.
        ;               For example to compare between "madam" & "ada" we need to compare *ada* portion of main string with substring ada, no more, no less     
        MOV SP, SI;     storing the index of current character of main string so if the following REPE CMPSB find mismatch then the process can be started over from the next character of main string (SEE line 1 of TEMPRED) by going to TEMPRED > FIND
        ADD SP, 0001H
        CLD
        REPE CMPSB
        JNE TEMPRED
        JMP GREEN

TEMPRED:;               substring not found starting from the current character of main string, but it is possible to find match if we start from next character in main string
        MOV SI,SP;      going to the next character of main string (after REPE CMPSB of CHECK segment)
        DEC DX
        LEA DI, STR2;   reloading substring index in DI (after REPE CMPSB of CHECK segment)
        JMP FIND;       if a character matches but the following substring mismatches in main string then we start over the same process from the next character of main string by going to FIND segment         

GREEN:  
        MOV BX, 0001H;  substring found
        JMP EXIT


RED:    
        MOV BX, 0000H;  substring not found
        JMP EXIT

EXIT:         
    CODE ENDS
    END
    RET
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top