在文本中搜索字符串

时间:2014-11-26 22:49:16

标签: string search assembly

我必须使用可以在文本中搜索字符串的x86程序集编写程序。我真的很努力,但我只是一个装配的初学者,只是不能做任何有用的东西。这是我试图写的,它可能真的搞砸了,但我会很高兴任何建议。至少它有什么好处吗?

%include 'rw32.inc'     ; library

[segment .data use32]   

sMessage1 db  "Hello World!",0      ;main text
sMessage2 db  "llo",0               ;searched string
sMessage3 db  "Searched string was found in main string",0
sMessage4 db  "Searched string was not found in main string",0 

[segment .code use32]   

prologue                ; macro


         mov di,sMessage1     
         mov si,sMessage2
         mov al,[si]
HOP:     cmp di,0
         je ENDOFTEXT
         cmp si,0
         je FINISHED    
         cld
         scasb
         jz HOP
         add si,1
         jmp HOP
ENDOFTEXT:
         mov si,sMessage3
         call WriteString
         jmp END
FINISHED:
         mov si,sMessage4
         call WriteString
END:          

epilogue                ; macro  

2 个答案:

答案 0 :(得分:0)

为什么我们不首先给你的变量一些合理的名字。我不了解您,但sMessage1sMessage2等不向我传达任何信息。

StringToSearch  db  "Hello World!",0      ;main text
StringToLookFor db  "llo",0               ;searched string
FoundMessage    db  "Searched string was found in main string",0
NotFoundMessage db  "Searched string was not found in main string",0 

这让我的事情变得更容易。

您走在正确的轨道上,但您的代码存在一些问题。首先,指令cmp di,0比较DI寄存器中的值,看它是否为0.你真正想做的是看DI指向的字节是否等于0.你想要的是什么:

mov ah,[di]
cmp ah,0
je ENDOFTEXT

将DI指向的值加载到寄存器中并将其与0进行比较。

cmp si,0行有同样的错误,您需要以同样的方式修复它。

现在,对于实际搜索,您有正确的想法,但算法过于简化。我不会给你一个完整的工作计划,因为我认为你是为了课堂作业而做的。但我可以指出你正确的方向。

基本理念是:

    textPosition = 0    // start of text
FindFirstCharacter:
    targetPosition = 0  // start of string to search for
    targetChar = stringToSearchFor[0]
    if text[textPosition] == 0 then done (failure)
    if text[textPosition] != targetChar    // scasb
        textPosition = textPosition + 1
        goto FindFirstCharacter

; At this point, textPosition is pointing to the position in the text
; that has the first character of the search string.
; Increment it, and save the position
    textPosition = textPosition + 1
    savePosition = textPosition

; now, we're looking for the following characters of the search string in the text.
SearchLoop:
    targetPosition = targetPosition + 1
    targetChar = stringToSearchFor[targetPosition]
    if targetChar == 0 then done (success)
    if text[textPosition] == 0 then done (failure)
    if text[textPosition] != targetChar    // scasb
        ; characters didn't match
        ; start over at savePosition
        textPosition = savePosition
        goto FindFirstCharacter
    ; Characters matched. Go for the next one
    textPosition = textPosition + 1
    goto SearchLoop

您应该能够将其转换为汇编语言。请记住我在text[textPosition]的位置,您想要[di],而searchString[targetPosition][si]

请注意,您需要内部循环,因为您可能匹配部分字符串。例如,请考虑以下文字:

Text = abcabdfe
SearchFor = abd

如果您只有一个循环,那么它会找到ab,但随后会在c失败并放弃。上面显示的算法将在c上失败,然后返回查找从c开始的第一个字符。

答案 1 :(得分:0)

您正在为32位Windows编程("使用32"),因此您应该避免使用16位内容(si,di),尤其是在访问内存时。每si更改一次& diesi& edi

cmp di,0更改为cmp byte [edi],0,将cmp si,0更改为cmp byte [esi],0。您想要比较字节值而不是地址。