Valhalla Legends Forums Archive | Assembly Language (any cpu) | Hmm... Question!

AuthorMessageTime
TheMinistered
Here is some useful information...
[code]
Public Sub RemoveCharacter(ByRef searchstring as String, Optional ByVal searchchar as Long = 32)

End Sub
[/code]

searchstring is defined as [esp+10h]
searchchar is defined as [esp+14h]

[code]
:00000000 57 push edi
:00000001 56 push esi
:00000002 8B7C2410 mov edi, dword ptr [esp+10]
:00000006 8B07 mov eax, dword ptr [edi]
:00000008 85C0 test eax, eax
:0000000A 7450 je 0000005C
:0000000C 8BF8 mov edi, eax
:0000000E 8B4FFC mov ecx, dword ptr [edi-04]
:00000011 668B442414 mov ax, word ptr [esp+14]
:00000016 6689040F mov word ptr [edi+ecx], ax
:0000001A D1E9 shr ecx, 1
:0000001C 41 inc ecx
:0000001D F2 repnz
:0000001E 66AF scasw
:00000020 752A jne 0000004C
:00000022 4F dec edi
:00000023 4F dec edi
:00000024 41 inc ecx
:00000025 8BF7 mov esi, edi
:00000027 F3 repz
:00000028 66AF scasw
:0000002A 7420 je 0000004C
:0000002C 4F dec edi
:0000002D 4F dec edi
:0000002E 41 inc ecx
:0000002F 8BD1 mov edx, ecx
:00000031 8BDF mov ebx, edi
:00000033 F2 repnz
:00000034 66AF scasw
:00000036 4F dec edi
:00000037 4F dec edi
:00000038 41 inc ecx
:00000039 2BCA sub ecx, edx
:0000003B F7D9 neg ecx
:0000003D 2BD1 sub edx, ecx
:0000003F 8BFE mov edi, esi
:00000041 8BF3 mov esi, ebx
:00000043 F3 repz
:00000044 66A5 movsw
:00000046 8BCA mov ecx, edx
:00000048 87F7 xchg edi, esi
:0000004A EBDB jmp 00000027
:0000004C C60600 mov byte ptr [esi], 00
:0000004F 8BC6 mov eax, esi
:00000051 8B7C2410 mov edi, dword ptr [esp+10]
:00000055 8B3F mov edi, dword ptr [edi]
:00000057 2BC7 sub eax, edi
:00000059 8947FC mov dword ptr [edi-04], eax
:0000005C 5E pop esi
:0000005D 5F pop edi
:0000005E 33C0 xor eax, eax
:00000060 C20C00 ret 000C
[/code]

I have a question that is related to line 16... i'm curious... is it just me or is it moving the contents @ ax to the end of the searchstring?? could anyone tell me what's going on there?
June 2, 2003, 11:10 PM
Yoni
[code]:00000011 668B442414 mov ax, word ptr [esp+14]
:00000016 6689040F mov word ptr [edi+ecx], ax[/code]
It's copying 2 bytes from [esp+14], i.e. searchchar, to [edi+ecx].

[code]:00000002 8B7C2410 mov edi, dword ptr [esp+10]
.....
:0000000E 8B4FFC mov ecx, dword ptr [edi-04][/code]
Looks like ecx is the length of searchstring.
(In a BSTR, the length is stored in p-4, where p is the BSTR pointer.)

Copying 2 bytes from searchchar to [edi+ecx] is something like:
[code]tempstring = searchstring & Chr(searchchar)[/code]
I say "tempstring" instead of "searchstring" because it doesn't seem to be updating the length ([edi-4]) until later.
June 3, 2003, 8:35 AM
TheMinistered
I already know that the length of the string is stored in the BSTR header... however, I don't agree with the following:
[code]
tempstring = searchstring & Chr(searchchar)
[/code]

it's more like this... (like you said...)
[code]
searchstring = left$(searchstring, len(searchstring) -1) & chr$(searchchar)
[/code]

It's actually replacing the null terminator with the search character. Then the entire string is scanned for the character. Placing it at the end makes sure it is eventually found, I suppose in case the string length is incorrect. Because repnz would stop once ecx hit zero, normally. Thank's for the help though, but a friend and I already figured it out :)

June 3, 2003, 11:53 AM
Yoni
What null terminator?

BSTRs don't have to be null terminated.
June 3, 2003, 1:34 PM
TheMinistered
In visual basic, they are null terminated (however, since it's unicode the null terminator takes up one word)
June 4, 2003, 3:28 AM
Skywing
[quote author=TheMinistered link=board=7;threadid=1525;start=0#msg11504 date=1054697336]
In visual basic, they are null terminated (however, since it's unicode the null terminator takes up one word)
[/quote]No, I think you're wrong there. If that were true, how would all of those Visual Basic packet buffer type classes which use VB Strings to store data which includes nulls work?
June 4, 2003, 5:27 AM
Adron
They might be like msvc's std::string - there is a null terminator but it's not part of the string. VB needs to generate null terminated strings every now and then and it would make sense to keep that null terminator there for when it's needed.
June 4, 2003, 9:49 AM
TheMinistered
Don't believe me skywing? Here:
[code]
Option Explicit

Private Declare Sub RtlMoveMemory Lib "kernel32" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Form_Load()
Dim s As String
Dim i As Integer

s = "foo"

RtlMoveMemory i, ByVal StrPtr(s) + LenB(s), 2
Debug.Print Hex$(i)
End Sub
[/code]

You can experiment to see the characters of the string by substituting 0, 2 and 4 for LenB(s). (Thanks go out to OnError for creating the above code while I was sleeping.)
June 4, 2003, 2:52 PM
Yoni
Your test doesn't deny Skywing's message - it confirms Adron's.

BSTRs may be null-terminated for various reasons. They don't have to be. When they happen to be null-terminated (where the null isn't actually part of the string), the length doesn't include the null.

In your example, "foo" happens to be null terminated. It doesn't have to be, though.

Try something like:
[code]Dim s As String, x As Integer
x = 1234
s = "foo"
RtlMoveMemory ByVal StrPtr(s) + 6, x, 2 ' Replace the possible null terminator with 1234
Debug.Print s ' It is not null-terminated, and yet, this doesn't crash!
x = Asc("d")
RtlMoveMemory ByVal StrPtr(s) + 6, x, 2 ' Replace the 1234 with "d"
x = 4 ' Depending on BSTR format, this might need to be 8 - forgot
RtlMoveMemory ByVal StrPtr(s) - 4, x, 1 ' Fix the length
Debug.Print s ' Should print "food"[/code]

(If I'm totally wrong here, tell me, as I wrote this directly to the forum and didn't test)
June 4, 2003, 7:11 PM
ninjaz
rofl, [vL] is yet to be proved wrong
July 10, 2003, 2:21 AM
TheMinistered
ninjaz, technically I was not wrong either. You need to read carefully.
July 12, 2003, 2:07 AM

Search