String 在汇编中,我想搜索一个字符串,替换一个单词,并显示新字符串

String 在汇编中,我想搜索一个字符串,替换一个单词,并显示新字符串,string,assembly,x86,String,Assembly,X86,我正在学习汇编课程,我已经写出了大部分程序,我只是在替换单词和显示新字符串时遇到了问题。这个问题需要一个句子、一个要查找的单词和一个要替换的单词。程序扫描字符串,替换单词的任何实例,并显示新字符串。 例如:“天空是蓝色的。” 要找到的词:“天空” 取而代之的是:“海洋” 新字符串:“海洋是蓝色的。” 以下是我到目前为止的情况: .586 .MODEL FLAT INCLUDE io.h ; header file for input/output .STACK 4096

我正在学习汇编课程,我已经写出了大部分程序,我只是在替换单词和显示新字符串时遇到了问题。这个问题需要一个句子、一个要查找的单词和一个要替换的单词。程序扫描字符串,替换单词的任何实例,并显示新字符串。
例如:“天空是蓝色的。” 要找到的词:“天空” 取而代之的是:“海洋” 新字符串:“海洋是蓝色的。”

以下是我到目前为止的情况:

.586
.MODEL FLAT

INCLUDE io.h            ; header file for input/output

.STACK 4096

.DATA
prompt1 BYTE    "String to Search: ", 0
prompt2 BYTE    "Word to Search For: ", 0
prompt3 BYTE    "Word to replace with: ", 0
target  BYTE    80 DUP (?)
key     BYTE    80 DUP (?)
strSub  BYTE    80 DUP (?)
trgtLength  DWORD   ?
keyLength   DWORD   ?
lastPosn    DWORD   ?
strSubLen   DWORD   ?
resultLbl BYTE  "The new sentence is: ", 0

.CODE
_MainProc PROC
    input prompt1, target, 80   ;input target string
    lea eax, target             ;address of target
    push eax                    ;parameter
    call strlen                 ;strlen(target)
    add esp, 4                  ;remove parameter
    mov trgtLength, eax         ;save length of target
    input prompt2, key, 80      ;input key string
    lea eax, key                ;address of key
    push eax                    ;parameter
    call strlen                 ;strlen(key)
    add esp, 4                  ;remove parameter
    mov keyLength, eax          ;save length of key
    input prompt3, strSub, 80   ;input word to search for
            lea eax, strSub             ;address of key
    push eax                    ;parameter
    call strlen                 ;strlen(strSub)
    add esp, 4                  ;remove parameter
    mov strSubLen, eax          ;save length of key

    mov eax, trgtLength
    sub eax, keyLength
    inc eax                     ;trgtLength - keyLength +1
    mov lastPosn, eax
    cld                         ;Left to Right comparison
    mov eax, 1                  ;starting position

    whilePosn:
        cmp eax, lastPosn       ;position <= last_posn?
        jnle endWhilePosn       ;exit if past last position

        lea esi, target         ;address of target string
        add esi, eax            ;add position
        dec esi                 ;address of position to check
        lea edi, key            ;address of key
        mov ecx, keyLength      ;number of position to check
        repe cmpsb              ;check
        jz found                ;exit of success
        inc eax                 ;increment position
        jmp whilePosn           ;repeat

    endWhilePosn:
        output resultLbl, [esi] ;display new sentence
        jmp quit

    found:
        sub edi, keyLength
        mov ecx, strSubLen
        lea esi, strSub
        cld
        rep movsb
        inc eax
        jmp whilePosn

    quit:
        mov     eax, 0  ; exit with return code 0
        ret
_MainProc ENDP


strlen  PROC
push ebp                    ;establish stack frame
mov ebp, esp
push ebx                    ;save EBX
sub eax, eax                ;length := 0
mov ebx, [ebp+8]            ;address of string

whileChar:
cmp BYTE PTR [ebx], 0       ;null byte?
je endWhileChar             ;exit if so
inc eax                     ;increment length
inc ebx                     ;point at next character
jmp whileChar               ;repeat

endWhileChar:
pop ebx                     ;restore registers
pop ebp
ret
strlen  ENDP
END
.586
.样板房
包括io.h;输入/输出的头文件
.堆栈4096
.数据
prompt1字节“要搜索的字符串:”,0
prompt2字节“要搜索的单词:”,0
prompt3字节“要替换为的字:”,0
目标字节80重复(?)
密钥字节80重复(?)
strSub字节80重复(?)
德沃德?
键长德沃德?
拉斯波森·德沃德?
斯特苏布伦·德沃德?
结果BL字节“新句子为:”,0
.代码
_MainProc PROC
输入提示1,目标,80;输入目标字符串
lea-eax,目标;目标地址
推动eax;参数
打电话给斯特伦;斯特伦(目标)
添加esp,4;删除参数
mov trgtLength,eax;节省目标的长度
输入提示2,键,80;输入键字符串
leaeax,key;钥匙地址
推动eax;参数
打电话给斯特伦;斯特伦(钥匙)
添加esp,4;删除参数
mov键长,eax;保存密钥的长度
输入提示3,strSub,80;输入要搜索的单词
lea eax,strSub;钥匙地址
推动eax;参数
打电话给斯特伦;strlen(strSub)
添加esp,4;删除参数
mov strSubLen,eax;保存密钥的长度
mov eax,trgtLength
子eax,密钥长度
公司eax;trgtLength-键长度+1
mov lastPosn,eax
cld;从左到右比较
mov-eax,1;起始位置
whilePosn:

cmp-eax,lastPosn;位置在x86汇编中处理字符串时,必须快速掌握
rep
指令。如果没有,你可能会在你的第一个项目完成之前去世

可以找到(或)关于汇编中字符串操作的非常好的介绍,但这里您真正需要的是以下内容:

  • :存储字符串
  • :扫描字符串
  • :比较字符串

您可以使用
xchg edi、esi
临时交换寄存器;或者您可以选择完全不同的寄存器分配。没有任何规定,例如,使用“ecx”作为计数器(除非您需要使用rep xxxx指令或循环)。有许多方法可以实现这一点,一些是快速的,一些是简单的。在字符串中插入字符串两者都不是,而且循环中区分大小写的比较速度很慢。用汇编语言编写优雅的解决方案是可能的,就像用任何语言一样。想想什么可以更简单或更快。在这种情况下,是否可以将单词拆分为一个字符串数组,方便地进行比较,并在完成后快速轻松地联接?另一种方法是放置匹配字符的标记字节,并在加入时跳过这些字节。装配工有一切可能重新发明一个更好的轮子我一点也不知道x86,但是如果strlen(搜索)的话,看起来你不会插入/删除字符=斯特伦(替换)。此外,在找到(eax)时,您需要跳过strlen(搜索)字符,而不仅仅是1个字符。(示例:将“xx”替换为“xxx”。)您仍然应该获得一些输出,输出是什么?你有没有一步一步地浏览代码并查看寄存器值?由于@Perror的第二个链接,我想我已经把问题缩小了一点,因为现在程序逐字节搜索
目标
,查找
。一旦找到
,它将跳转到
找到的代码块
,然后使用
stosb
它尝试将
strSub
复制到
taregt
中。问题是,它只是复制strSub的第一个字母,然后在我要保存的字符串部分上向后复制。好的,所以我将
找到的代码块
编辑为我现在拥有的,我发现通过将
stosb
更改为和
movsb
并调整我的esi和edi指针,它复制整个字符串,而不仅仅是一个字母。此外,程序不是向后复制,而是在字符串开头复制。就像它不会从程序找到
键的地方开始复制一样。您的第二个链接在解释上述说明时非常有用。我意识到我是从错误的角度出发的。我的程序仍然有问题,但到目前为止你提供了最多的帮助。谢谢。
repe
/
repne
-字符串说明适用于已知
strlen
的显式长度字符串。在当前的CPU上,它们的速度并不比每次字节循环快。(只有rep MOV/stos memcpy/memset是快速的。)