汇编实验——查找匹配字符串

本文详细介绍了汇编实验的过程,主要内容包括查找匹配字符串的算法实现。难点在于将匹配到的16位二进制关键字转换为4位16进制数,并在句子中正确查找关键字。实验中,通过循环移位和加法操作实现了二进制到16进制的转换。此外,还讨论了比较字符串和恢复指针的逻辑,以及避免错误地显示未匹配成功时的地址。


        具体实验代码,search.asm如下:

;数据段

;**********************************************

datarea         segment

             

      string1          db         "Enterkeyword:$"

      string2          db         "Entersentence:$"

      string3          db         "Matchat location:$"

      string4          db         "Nomatch!",13,10,"$"

      string5          db         "Hof the sentence.$"

      keyword          db         50D,?,50DDUP(?) ;0A功能调用:最大输入50个字符,实际输入个数,存放的字符

      sentence         db         50D,?,50DDUP(?)                     

datarea         ends

;**********************************************

;代码段

;**********************************************

prognam      segment

;----------------------------------------------

      main      procfar

             assume         ds:datarea,cs:prognam,es:datarea

      

      start:

             push        ds

             sub         ax,ax

             push        ax

             

             mov         ax,datarea

             mov         ds,ax

             mov         es,ax

             

             lea         dx,string1             ;显示字符串1

             mov         ah,09h

             int         21h

             

             lea         dx,keyword          ;输入关键字

             mov         ah,0Ah                 

             int         21h

 

                           

             mov         ah,02h                 ;显示输出换行     

             mov         dl,0Ah

             int         21h

 

             lea         dx,string2             ;显示字符串2

             mov         ah,09h

             int         21h

 

             lea         dx,sentence          ;输入句子

             mov         ah,0Ah

             int         21h

 

             

             mov         ah,02h                 ;输出换行

             mov         dl,0Ah

             int         21h

 

             lea         si,keyword+2;从第三个字节开始

             lea         di,sentence+2

 

             mov         ax,0

             mov         al,[sentence+1]

             mov         ah,[keyword+1]

             cmp         al,ah             ;比较关键字和句子的长度

             ;jnl        right

             jl          wrong

 

             ;lea        dx,string4

             ;mov        ah,09h

             ;int        21h

             ;jmp        exit

 

      ;right:

             sub        al,ah

             mov        ah,0

             add        al,1

             mov        cx,ax                           ;循环次数

                    

 

 

             

      compare:

            push      cx

      ;     mov      cx,ax

      ;     cld                                            ;使变址寄存器SI和DI的地址指针自动加1

      ;     repz cmpsb

      ;     jz           match

      ;

      ;     sub        ax,cx

      ;     sub        si,ax

       

             mov        cx,3               

             cld

             repz cmpsb

             jz         match

      ;未比较成功

             mov        ax,3              

             sub        ax,cx

             sub        si,ax              ;关键词回到词首

             mov        ax,2

             sub        ax,cx

             sub        di,ax

             pop        cx

             loop compare

;----------------------------------------------------------------

      wrong:

             lea        dx,string4

             mov        ah,09h

             int        21h

             jmp        exit

      

 

;----------------------------------------------------------------

      match:

             pop         cx

             mov         bx,di                    ;DI指向句子中字符串匹配成功的最后一个字符 

             

             lea         dx,string3

             mov         ah,09h

             int         21h

 

             sub        bx,offset sentence+2

             sub        bx,2       ;BX存入首地址所在字符串中的地址,即匹配到关键字的首位置

 

             call change                ;将位置用16进制数表示

 

             lea         dx,string5

             mov         ah,09h

             int         21h

;----------------------------------------------------------------------

 

 

 

      exit:

             mov      ah,4ch

             int         21h

             ret

 

      main      endp

;-----------------------------------------------------------

;附加段

;*****************************************************************************

 

      change         procnear

 

             push      ax

             push      bx

             push      cx

             push      dx

 

             mov      ch,4

             mov      cl,4

;-------------------------------------------------------------------------

      rotate:                                       ;把四位二进制数转换为ASCII码

             rol       bx,cl

             mov       al,bl

             and       al,0Fh

 

             add       al,30h

             cmp       al,3Ah

             jl        printit

             add       al,7h

;--------------------------------------------------------------------------

      printit:

             mov         dl,al

             mov         ah,2

             int         21h

 

             dec         ch

             jnz         rotate

 

             pop        dx

             pop        cx

             pop        bx

             pop        ax

             ret

      change         endp

;****************************************************************************

prognam      ends

;****************************************************************************

             end       start





       该实验是查找匹配字符串,其难点有两处:


       一个是将句子中匹配到的关键字的首地址16位二进制数表示为416进制数,这个问题在课本上有具体实例。我通过添加一个附加段change实现该功能,具体实现思路为,将dx中存储的16位二进制数依次进行四位的循环左移,将移入低位的高四位再进行加30h(另一种情况会再加7)操作,最后实现输出为416进制地址。


       第二个问题是本实验的关键,在句子中查找是否存在之前输入的关键字。首先需要有输入限制要求,即输入的关键字长度不能大于句子的长度。然后是比较句子中的字符和关键字,利用cld依次将sidi1repz cmpsb比较sidi指向的字符,若三次比较均成功,则跳转至match(表示匹配成功),在match中实现将句子中匹配成功的首地址存放在bx中。否则继续下面的执行,恢复si指针指向关键字首地址,di指向句子的匹配失败的首地址的下一个地址,然后继续循环compare(继续寻找匹配),若最后失败则执行到wrong


       在该实验中,我犯了一个错误,将wrong的操作放在了关键字长度不小于句子长度的判断后面,如此,实际上在之后的匹配中,即使最后没有找到匹配成功的关键字,但程序会显示句子中最后一次尝试匹配的首地址。显然这是不正确的。




程序接收用户键入的一个关键字以及一个句子。如果句子中不包含关键字则显示’no match’;如果句子中包含关键字则显示‘match’,且把该字在句子中的位置用十六进制数显示出来,要求程序的执行过程如下: enter keyword :abc enter sentence :we are studying abc match at location :11H of the sentence enter sentence: xyz ,ok? no match enter sentence :^c 四. 方法说明: 程序可由三部分组成: (1 ) 输入关键字和一个句子,分别存入相应的缓冲区中,可用功能调用0AH。 (2) 在句子中查找关键字。 1. 关键字和一个句子中相应字段的比较可使用串比较指令,为此必须定义附加段,但附加段和数据段可以定义为同一段,以便于串指令的使用,这样,相应的寄存器内容也有了确定的含义,如下: SI 寄存器为关键字的指针 DI 寄存器为句子中正相比较的字段的指针 CX寄存器存放关键字的字母个数(长度) 2. 整个句子和关键字的比较过程可以用一个循环结构来完成。循环次数为: (句子长度--关键字长度)+1在计算循环次数时,如遇到句子长度小于关键字长度的情况则应转向显示“no match”,循环中还需要用到BX寄存器,它用来保存句子中当前正在比较字段的首地址。 (3) 输出信息: 用功能调用09h分“找到”或“找不到”两种情况分别显示不同的信息。在“找到”时,还要求显示出匹配字符串在句子中的位置,在“找到”时BX寄存器的内容为匹配字符串的首地址,将此值减到句子的首地址,再将差值加1 即是所要的匹配字符串在句子中的位置,可将位置转换为十六进制数从屏幕上显示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值