Hello everyone,
I tried to write a function to replace all occurences of a substring in a string by other substring, but it didn't work. It crashes my system and I have to reboot.
==================================

ReplaceString proc Phrase:DWORD,SourceWord:DWORD,ReplaceWord:DWORD
LOCAL PosSW:DWORD
LOCAL LenSW:DWORD
LOCAL LenRW:DWORD
LOCAL Phrase2:DWORD
LOCAL tmpstr1:DWORD
LOCAL tmpstr2:DWORD
LOCAL LenPhrase:DWORD

invoke lstrcpy, Phrase2, Phrase
invoke lstrlen, SourceWord
mov LenSW, eax
invoke InString, 1, Phrase2, SourceWord
mov PosSW, eax
.WHILE PosSW>0
sub PosSW, 1
invoke szLeft, Phrase2, tmpstr1, PosSW
mov ecx, LenSW
add PosSW, ecx
add PosSW, 1
invoke lstrlen, Phrase2
sub eax, PosSW
mov LenPhrase, eax
invoke szRight, Phrase2, tmpstr2, LenPhrase
invoke szMultiCat, 3, Phrase2, tmpstr1, ReplaceWord, tmpstr2
invoke InString, 1, Phrase2, SourceWord
mov PosSW, eax
.ENDW
invoke lstrcpy, eax, Phrase2
ReplaceString endp

======================================
What I've done wrong?
Can anyone help me?
Does anyone have a function that does this?
Thanks in advance. Sorry for my bad english.
Posted on 2001-12-09 11:27:26 by dilau
Where you can get into trouble is if the total length with the replacements is longer than the original buffer. One or more replacement will make the written data longer than the data that is read and you will over run the original buffer.

The replacement algo is not that complicated, just scan for the bytes you wish to replace, write the replacement at that offset, calculate the length of the original from the source and move that far along the data to write the next byte.

What you need is some form of memory allocation strategy so that the buffer length is never exceeded.

Regards,

hutch@movsd.com
Posted on 2001-12-09 15:59:29 by hutch--
Thanks, hutch! =)
I realized that I was doing the wrong way. I decided to learn to do this without using already made functions like InString, szMid, etc. I was doing it like I've done in Delphi. I think now I am really learning Assembly. I spent the whole day reading tutorial about working with string in asm.
I wanna thank you hutch (You wrote asmintro.hlp that comes with the Masm32v7 package, right? The topic "Working with Strings" really helped me a lot.) and (I am posting his string tutorial in attachment).
And here is my function:
==================================

ReplaceString proc StrSource:DWORD,StrDest:DWORD,SubStrSource:DWORD,SubStrDest:DWORD
LOCAL esi1:DWORD
LOCAL lensubstr:DWORD
push esi
push edi
push ebx
push edx

invoke lstrlen, SubStrSource
sub eax, 1
mov lensubstr, eax

cld
mov esi, StrSource
mov edi, StrDest
mov ebx, SubStrSource
mov edx, SubStrDest

compare:
mov al,
inc esi
mov ah,
cmp al, ah
je compare2
comparesub:
cmp al, 0
je theend
mov , al
inc edi
jmp compare

compare2:
mov esi1, esi
dec esi
loopc2:
mov ah,
inc ebx
mov cl,
inc esi
cmp ah, 0
je found
cmp ah, cl
jne backtocompare

found:
mov esi, esi1
add esi, lensubstr
mov ebx, SubStrSource
copynewstr:
mov ah,
inc edx
cmp ah, 0
je foundend
mov , ah
inc edi
jmp copynewstr
foundend:
mov edx, SubStrDest
jmp compare

backtocompare:
mov esi, esi1
mov ebx, SubStrSource
jmp comparesub

theend:
mov StrSource, edi
pop edx
pop ebx
pop edi
pop esi
ret
ReplaceString endp

==================================
What do you think, hutch?
Does anyone have any suggestions to improve my code?
Posted on 2001-12-10 11:00:51 by dilau
I found a bug in my code... I forget one line:
jmp loopc2
Right after:
jne backtocompare

Now I have other problem, how can I replace a substring in a string without having to having a destination buffer?
I have to do several replacements in a string.

Here is the code again:
=========================
ReplaceString proc StrSource:DWORD,StrDest:DWORD,SubStrSource:DWORD,SubStrDest:DWORD
LOCAL esi1:DWORD
LOCAL lensubstr:DWORD
push esi
push edi
push ebx
push edx

invoke lstrlen, SubStrSource
sub eax, 1
mov lensubstr, eax

cld
mov esi, StrSource
mov edi, StrDest
mov ebx, SubStrSource
mov edx, SubStrDest

compare:
mov al,
inc esi
mov ah,
cmp al, ah
je compare2
comparesub:
cmp al, 0
je theend
mov , al
inc edi
jmp compare

compare2:
mov esi1, esi
dec esi
loopc2:
mov ah,
inc ebx
mov cl,
inc esi
cmp ah, 0
je found
cmp ah, cl
jne backtocompare
jmp loopc2

found:
mov esi, esi1
add esi, lensubstr
mov ebx, SubStrSource
copynewstr:
mov ah,
inc edx
cmp ah, 0
je foundend
mov , ah
inc edi
jmp copynewstr
foundend:
mov edx, SubStrDest
jmp compare

backtocompare:
mov esi, esi1
mov ebx, SubStrSource
jmp comparesub

theend:
mov StrSource, edi
pop edx
pop ebx
pop edi
pop esi
ret
ReplaceString endp
Posted on 2001-12-10 16:14:40 by dilau
I found another bug! I forget to put the 0 at the end of the destination string.
I hope it is my last bug.
Here is the correction:
=============================
ReplaceString proc StrSource:DWORD,StrDest:DWORD,SubStrSource:DWORD,SubStrDest:DWORD
LOCAL esi1:DWORD
LOCAL lensubstr:DWORD
push esi
push edi
push ebx
push edx

invoke lstrlen, SubStrSource
sub eax, 1
mov lensubstr, eax

cld
mov esi, StrSource
mov edi, StrDest
mov ebx, SubStrSource
mov edx, SubStrDest

compare:
mov al,
inc esi
mov ah,
cmp al, ah
je compare2
comparesub:
mov , al
cmp al, 0
je theend
inc edi
jmp compare

compare2:
mov esi1, esi
dec esi
loopc2:
mov ah,
inc ebx
mov cl,
inc esi
cmp ah, 0
je found
cmp ah, cl
jne backtocompare
jmp loopc2

found:
mov esi, esi1
add esi, lensubstr
mov ebx, SubStrSource
copynewstr:
mov ah,
inc edx
cmp ah, 0
je foundend
mov , ah
inc edi
jmp copynewstr
foundend:
mov edx, SubStrDest
jmp compare

backtocompare:
mov esi, esi1
mov ebx, SubStrSource
jmp comparesub

theend:
mov StrSource, edi
pop edx
pop ebx
pop edi
pop esi
ret
ReplaceString endp
Posted on 2001-12-10 16:24:16 by dilau