Hey
I know there are a few of you who have experience in other languages (well, probably most of you). I was wondering, is there a MASM replacement for the Substring function? I used to use it in VB.Net, but now that I've switched to MASM, I don't know what else to use. Here's a little example (my vb skills have kind of worn away if something isn't quite right):


Dim OldText As String ' Declare "OldText" as a string
Dim NewText As String ' Declare "NewText" as a string (obviously)
OldText = "333Hello"
NewText = OldText.Substring(3,0) ' Trim "333Hello" to "Hello"

For those of you unfamiliar, the first param to the Substring function is where to start copying characters (0-based) and the second is how many characters to copy. If the second param is 0, it copies the rest of the characters in the string after the the starting point.
If there is no such macro or proc type function that does this in MASM, than a raw assembler example is welcome.
Posted on 2004-09-30 17:19:53 by yo|dude|mon


Substring MACRO P1, P2, P3, P4

cld
mov esi, P1+P3
mov edi, P2
mov ecx, P4

test ecx, ecx
je @f

rep movsb
jmp @l1

@@: lodsb
stosb
test al, al
jne @b

@l1:
ENDM


.data


instrng db "333Hello",0
outstrng db 6 dup (0)


.code

Substring offset instrng, offset outstrng, 3, 0
Posted on 2004-09-30 18:27:43 by arafel
arafel, that's unsafe code - what if the source string is smaller than the substring index? In these times of buffer overflows and whatnot, such code is a big no-no.
Posted on 2004-09-30 18:55:02 by f0dder
it isn't supposed to be a safe one :)

it's just an example showing the direction. of course bounds checking should be implemented.
Posted on 2004-09-30 19:14:28 by arafel
Works great! Thanks a lot. One more thing, in your earlier post (before the macro) you had something like:


cld
mov esi, offset oldstr+3
mov edi, offset newstr
mov ecx, 5

rep movsb
...........

When I changed that "+ 3" to "+ eax", MASM gave me an error. When I changed it to "+ Dd", Dd being a dword set to 3, the program crashes. How come putting variables/registers in place of that 3 only works inside the macro?
Posted on 2004-09-30 19:16:42 by yo|dude|mon
Actually, I can't use variables in the macro either. How can I?
Posted on 2004-09-30 19:37:21 by yo|dude|mon
yo|dude|mon:

Ignore the first post before editing, I wanted to show some code snippets than I decided to rewrite it as macro.

Better use this code only as example for writing something more better. Because as f0dder mentioned there is problem with that code.
You could rewrite it as call function if size is your concern. Or break down it to separate parts and use where relevant. etc.

added:
You can't use variables because this macro process parameters only as constant values. i.e:
When 'mov esi, P1+P3' expanded with constant it becomes 'mov esi, offset something+integer' = valid. But when using variables as two last params the macro expands into invalid instruction.
replace
mov   esi, P1+P3 

by
mov esi, P1

add esi, P3
Posted on 2004-09-30 19:47:44 by arafel
Ran into a problem: when I call the macro twice in a row, MASM says "Symbol redefinition: "@l1"". How do I correct this?
Posted on 2004-09-30 20:45:11 by yo|dude|mon
Should I make the macro a proto?
Posted on 2004-09-30 21:04:51 by yo|dude|mon
define '@l1' as Local
Posted on 2004-09-30 21:06:53 by arafel
Cool, thanks. I know you've probably had enough of my questions, but I can't use a variable on that last argument. The macro treats whatever the value in the variable as if it was 0 and copies the string to the end.
Posted on 2004-09-30 21:18:00 by yo|dude|mon
This should remove problems with variables, bound checking, etc.
Substring MACRO instrng_addr, outbuffer_addr, outbuffer_size, starting_char, chars_to_copy


Local @l1,@l2,@l3

pushad

push outbuffer_size
push outbuffer_addr
push instrng_addr
push starting_char
push chars_to_copy

cld

pop ecx
pop esi
pop eax
add esi, eax
pop edi
pop edx

test ecx, ecx
je @l2

cmp edx, ecx
ja @l1
mov ecx, edx
dec ecx

@l1:
rep movsb
jmp @l3

@l2:
dec edx
jz @l3

lodsb
stosb
test al, al
jne @l2

@l3:
mov [edi], byte ptr 0
popad

ENDM

...I was too lazy to type something useful at a first time :-D
Posted on 2004-09-30 23:37:09 by arafel
Why do people use macros for the purpose of repeating the exact same code over and over? It's no wonder most programs these days are several megabytes in size. Please, if you need to have some repeating block for some reason, auto-generate it.
Posted on 2004-10-01 02:24:56 by Sephiroth3
yo|dude|mon,

Did you check the string functions coming with Hutch's masm32.lib?
Posted on 2004-10-01 04:59:02 by Vortex
Sephiroth, what do you mean by auto-generating it?
Posted on 2004-10-01 15:05:17 by yo|dude|mon
I suppose that was directed at me. Sorry if iam wrong.
Why do people use macros for the purpose of repeating the exact same code over and over? It's no wonder most programs these days are several megabytes in size.

If you read more carefully previous posts you will see that I didn't actually advised any macro usage.
Posted on 2004-10-01 15:28:07 by arafel
Guys, its very much pick the right capacity for the task at hand, macros are very useful as direct code insertion and written properly they have less overhead than procedures and can be used to target time/speed critical tasks.

Procedures are more space efficient so unless the code is truly time/speed critical, a procedure is a good choice especially if it is called from many other places.
Posted on 2004-10-01 22:46:09 by hutch--