【问题标题】:8086 masm program to search substring8086 masm 程序搜索子串
【发布时间】:2014-05-03 02:59:00
【问题描述】:

我有一个 8086 汇编语言程序来找出给定的子字符串是否存在于主字符串中。 当子字符串是单个字符时它工作正常。否则不是。 帮我找出错误。

这是我的代码 sn-p

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

【问题讨论】:

  • 请为您的标签选择比l0l1m1等更好的名称。
  • 在l0中读取第一个字符串并找到它的长度并存储到sl中。在l2中读取子字符串并将长度存储到ssl中。在l5中找到子字符串的起始字母位置.in l6 检查子字符串和主字符串的剩余字符是否相等。
  • 子字符串为单个字符时可以正常工作。但子字符串包含多个字符时则不行。
  • 在调试器中运行程序或添加一些调试打印,以便您知道它停止匹配字符串的位置和原因。
  • 汇编器确实有输入代码 cmets 的机制。您可能想要使用该功能。

标签: assembly x86 masm x86-16 masm32


【解决方案1】:

这是我的代码 sn-p,用于查找块缓冲区中是否存在(子)字符串,发布于 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

【讨论】:

  • 这如何回答 OP 的问题?他需要帮助来调试他的代码,而不是用其他人的代码替换它。
【解决方案2】:

Rajil kv 试试这个代码...我希望它可以工作...实际上我只是编辑了您自己的代码...所以我不能保证它是 100% 工作...所以请检查并提供您的反馈

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

【讨论】:

  • 欢迎来到 Stack Overflow Amith :) 鼓励在这里解释一下你在做什么。虽然工作代码可能对某些人有用,但通常不是。原因是提出问题的人显然对语言/算法有一些误解。所以解释会帮助他们理解。这样就不需要工作代码了(但只是上面的糖)。
  • Amith : 检查 ath 作为字符串和 ath 作为子字符串。我刚刚调试了你的代码,现在它工作正常。无论如何谢谢
【解决方案3】:
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

【讨论】:

    【解决方案4】:

    你可以试试我的代码:

    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
    

    【讨论】:

      【解决方案5】:
      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多