【发布时间】:2020-01-01 20:51:01
【问题描述】:
您好,我是Assembly 的新手,我在练习中遇到了一些问题,要求我在原始字符串中查找子字符串,如果找到,则将其替换为另一个给定的字符串。
示例: original string = "这个字符串是字符串";
要查找的字符串 = "字符串"
字符串替换 = "dog"
输出="这条狗是狗"
void main()
{
//Input
char stringa[1024] = "This string is a string";
char str1[] = "string"; // string to find
char str2[] = "dog"; // string to replace
// Output
char risultato[1024];
__asm
{
LEA EDI, stringa
MOV EAX, EDI //EAX like 'i' in stringa
LEA EDI, risultato
MOV ECX, EDI //ECX like 'j' in risultato
//finding str1 in stringa
MOV EDI, EAX
LEA ESI, str1
search:
MOV BL, [ESI] //current char of str1
//if i'm at the end of str1
//mean that str1 is in stringa
CMP BL, 0
JZ found
CMP[EDI], 0 //check if end of stringa
JZ fine
//otherwise
CMP[EDI], BL
JNE notfound
INC EDI
INC ESI
JMP search
found:
MOV EAX, EDI
DEC EAX
LEA ESI, str2 //sostitution of str1 with str2
sostituisci:
MOV BL, [ESI] //current char of str2
CMP BL, 0 //checj the end of str2
JZ continua
//otherwise
MOV EDI, ECX
MOV [EDI], BL //str2 paste in risultato
INC ECX
INC ESI
JMP sostituisci //next position in str2
notfound:
MOV EDI, EAX
MOV ESI, ECX
MOV BL, [EDI]
MOV [ESI], BL
INC ECX
continua:
LEA ESI, str1
INC EAX
MOV EDI, EAX
CMP [EDI], 0
JNE search
fine:
}
// output
printf("New string: %s\n", risultato);
}
我不明白为什么我的代码不能正常工作。 输出是:
新字符串:这条狗是狗╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠狗
而不是New string: This dog is a dog.
这些符号的原因是什么?
【问题讨论】:
-
大概你忘了在你的
char[]缓冲区的正确位置放置一个0字节作为终止符来标记隐式长度C字符串的结尾。在调试模式下,MSVC 使用0xCC字节毒化堆栈;大概╠是那个字节的字符。这使得调试函数更容易,因为错误比可能包含一些零字节的随机垃圾更明显。无论如何,使用调试器。 -
您可以看到如何检查源字符串中的零。您可以找到这个零,因为在 C 和 C++ 中,当您执行
char str2[] = "dog";之类的操作时,从"dog"编译的初始值是四个字节长,三个字节代表字母,第四个字节为零。这就是为什么您在 C 的输入字符串中搜索零的原因。但是在新字符串中你没有在末尾写零 = 字符串不是以零结尾的 = 它不是有效的 C 字符串。 -
完美,谢谢。我试图把 0 a 放在最后,但没有任何改变。出于这个原因,我认为我的代码中还有其他错误。可能我没有把它放在正确的位置。
-
@sof23 在调试器中使用内存视图以单个字节值的形式查看自己的内存内容。在单步执行每条指令时使用此视图,然后您可以观察在每次写入内存指令后如何逐字节构建结果字符串。然后,如果您确实尝试添加零(可能在
fine:标签之后),您应该在新字符串之后在内存中看到这个零字节。也许您有其他逻辑错误导致您无法正确检测到任务结束,或者您确实将零意外写入源字符串之一而不是结果字符串,...调试器有帮助:) -
尝试使用 "\0" 而不是 0 : "This string is a string\0".
标签: string assembly visual-c++ x86 inline-assembly