Hello again :P
I'm just wondering, how do we split strings in asm?
In c#, I did this way:
string[] parts = stringToSplit.Split(new char[]{'/'}); // split in every /
parts[0]
parts[1]
etc..
How it's done in asm?
You can create a loop and loop through the first string copying to the second until the delimiter is reached ie
mov esi, String1
mov edi, String2
oexNext:
cmp [esi], BYTE PTR 'delimiterchar'
je oexStringCopied
mov al, [esi]
mov [edi], al
inc esi
inc edi
jmp oexNext
oexStringCopied:
Or by length....
mov esi, String1
mov edi, String2
mov ecx, Length
rep movsb
ok, i'll try my luck.
what is movsb?
Let me know if you get stuck.... Also check the instructions meaning ie movsb in the masm32 help files they auto increment esi and edi and decrement ecx
movsb = move single byte (esi->edi)
I made a mistake in my first example please recheck it (first example just fixed ::)) Note you would replace 'delimiterchar' with for example BYTE PTR ',' or just numeric ascii byte 32 (space)
where my splited string will be at?
And, how I should use it?
I mean, esi[0], esi[1]...
OK so if you allocate a string the length of the expected string ie
mov esi, chr$("Split String Example, Split On Comma")
mov edi, alloc(24)
xor ecx, ecx
oexNext:
cmp [esi], BYTE PTR ','
je oexStringCopied
mov al, [esi]
mov [edi], al
inc ecx
inc esi
inc edi
jmp oexNext
oexStringCopied:
sub esi, ecx ; Subtract Copied Length
print esi ; Prints "Split String Example"
Note that the string allocated is longer than the destination string by 4 bytes.... You want at least 1 '0' byte at the and for a zero delimited string
each time you give me a different example, I'm getting a bit confused...
Lets just say the string I want to split at each , is "My car, is, red."
So spliting, I'd have:
My car
is
red
And I want to show a MessageBox with every splitted string.
MessageBox -> My car
MessageBox -> is
MessageBox -> red
You can do this with the code in my last post above, this code is effectively the same as the first example.... Try to understand these 2 examples to answer your own question so you can adapt it to your desired implementations
error A2008 - syntax error: esi
error A2006 - undefined symbol: chr$
error A2006 - undefined symbol: alloc
Quote from: lelejau on December 16, 2010, 04:54:47 PM
error A2008 - syntax error: esi
error A2006 - undefined symbol: chr$
error A2006 - undefined symbol: alloc
ok I was including /masm32/macros/macros.asm
including it gives me alot of errors...
I'll have to leave someone else to answer this I cant think of what you need to include with macros.asm maybe masm32 lib almost definately windows.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
Without macros.... Where were your strings (what variables are they in?).... There are other considerations if you use for example a predeclared BYTE buffer ie
LOCAL szBuffer[500]:BYTE
Such as zeroing the buffer and setting esi via
lea esi, szBuffer
Here is a working example, I hope it is clear enough. Use \masm32\help\opcodes.chm to learn about e.g. rep scasb and lodsd
include \masm32\include\masm32rt.inc
.data?
TheArray dd 100 dup(?) ; create space for 100 strings
TheCopy db 1000 dup(?) ; we need a copy
.code
txMyCar db "My car,is,red.", 0
start:
TheBranch=1 ; try #2
mov esi, offset txMyCar ; our source string
mov edi, offset TheCopy ; we create a copy
push edi ; we need edi again, so save it
mov ecx, len(esi) ; we need a limit
push ecx ; we need ecx again, so save it
rep movsb
pop ecx ; ecx is back
pop edi ; edi is back
mov al, "," ; we search for commas
mov ebx, offset TheArray ; we put the pointers into [ebx]
.Repeat
mov edx, edi ; save the current pointer start
repne scasb ; look in [edi] for matches to al
mov [ebx], edx ; store the start of the string
mov byte ptr [edi-1], 0 ; wipe out the comma, and put a zero delimiter instead
add ebx, 4 ; increase ebx by a dword
test ecx, ecx ; have we reached the limit?
.Until Zero?
if TheBranch eq 1
mov esi, offset TheArray ; start of array pointers
.Repeat
lodsd ; mov eax, [esi] plus add esi, 4
.Break .if !eax ; eax = 0 means end of pointers
print eax, 13, 10 ; print it...
.Until 0
else
print TheArray[0], 13, 10
print TheArray[4], 13, 10
print TheArray[8], 13, 10
endif
inkey "OK?"
exit
end start
:lol thanks jj
include \masm32\include\masm32rt.inc
was what I was thinking
Thanks, it worked perfectly.
Just answer me something, what TheBranch=1 is for?
I missed that.
Quote from: lelejau on December 16, 2010, 05:21:26 PM
Just answer me something, what TheBranch=1 is for?
It is called "conditional assembly". Masm generates either the loop code, or the three print statements. Good for testing variants.
Still dont get it.
Masm generates different code depending on the value of TheBranch. The first variant uses a loop, the second one
- , [4] etc to get the address of array elements; this is less flexible, of course.
You can see the difference if you run the executable(s) with OllyDbg.
if TheBranch eq 1
mov esi, offset TheArray ; start of array pointers
.Repeat
lodsd ; mov eax, [esi] plus add esi, 4
.Break .if !eax ; eax = 0 means end of pointers
print eax, 13, 10 ; print it...
.Until 0
else
print TheArray[0], 13, 10
print TheArray[4], 13, 10
print TheArray[8], 13, 10
endif
ok, thanks.