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是快速的。)