flat assembler
Message board for the users of flat assembler.

Index > Windows > How to work with strings?

Author
Thread Post new topic Reply to topic
BlastWave



Joined: 05 Oct 2006
Posts: 6
BlastWave 05 Oct 2006, 23:24
Im tryin' to play with some strings and fasm.
What i want to do is simply Mid String.
Like if you had a string "hello world",0
i wanted to make it mid(str,2) so it would be "llo world",0
i've try quite much all from push to pop to mov.

but when i do like this:
mov eax,[temp + 1]
mov [temp],eax

its accutly work but when i do it again or.
mov eax,[temp + 5]
mov [temp],eax


It trash my string,
i've used GlobalAlloc, dword(pointer to memory allocated)

Please don't give me lstrcat,lstrcpy,lstrcpyn,lstrcmp,lstrcmpi its not that im lookin' for.

sorry if bad explantion but ima kinda crappy explaling in english.
Post 05 Oct 2006, 23:24
View user's profile Send private message Reply with quote
Goplat



Joined: 15 Sep 2006
Posts: 181
Goplat 05 Oct 2006, 23:41
The easiest way to have all but the first N characters of a nul-terminated string is to just use the pointer str + N instead of str.
Post 05 Oct 2006, 23:41
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Oct 2006, 00:53
Code:
proc mid, dest, src, index
  push ebx

  mov ebx, [src]
  mov edx, [dest]
  add ebx, [index]
  xor ecx, ecx

@@:
  mov al, [ebx+ecx]
  mov [edx+ecx], al
  inc ecx
  test al, al
  jnz @b

  pop ebx
  ret
endp
    


The code above is what you mean?

About moving using DWORDs the problem is that you must be sure that the string has a size multiple of 4 bytes (I mean its size, no its actual length). If the strings are actually a struc with a field holding the string length then you can move by DWORD quantities [string.len shr 2] times and then move by BYTE quantities [string.len and 3] times to move the remainder bytes.

Note that the code is actually a strcpy which starts doing what Goplat said.
Post 06 Oct 2006, 00:53
View user's profile Send private message Reply with quote
BlastWave



Joined: 05 Oct 2006
Posts: 6
BlastWave 06 Oct 2006, 09:36
locodelassembly wrote:
Code:
proc mid, dest, src, index
  push ebx

  mov ebx, [src]
  mov edx, [dest]
  add ebx, [index]
  xor ecx, ecx

@@:
  mov al, [ebx+ecx]
  mov [edx+ecx], al
  inc ecx
  test al, al
  jnz @b

  pop ebx
  ret
endp
    


The code above is what you mean?

About moving using DWORDs the problem is that you must be sure that the string has a size multiple of 4 bytes (I mean its size, no its actual length). If the strings are actually a struc with a field holding the string length then you can move by DWORD quantities [string.len shr 2] times and then move by BYTE quantities [string.len and 3] times to move the remainder bytes.

Note that the code is actually a strcpy which starts doing what Goplat said.

Ty for the fast answer both of ya.
but not working :o
Code:
invoke GlobalAlloc,GMEM_FIXED,1024
mov [temp],eax
invoke GlobalAlloc,GMEM_FIXED,1024
mov [text],eax
; ReadFile to temp
stdcall mid,text,temp,10
invoke MessageBox,0,text,text,0
    

i've also read a bit try test things for my self.
I've found out load effect address works but not back to a dword.
Like

lea ecx,[temp + 13]
invoke MessageBox,0,temp,0,0

but when i want to make it to my dword again it get trash.
mov [temp],ecx
same with push lea etc.
Man i don't get this should't it just be a pointer?


EDIT.
i've just found out.
mov dword[temp + 1024],ecx
work but why the size of the allocated memory?

thanks
Post 06 Oct 2006, 09:36
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 06 Oct 2006, 10:34
Code:
lea ecx,[temp + 13] 
invoke MessageBox,0,temp,0,0    
you probably meant "ecx" instead of "temp" as second MessageBox's argument
Post 06 Oct 2006, 10:34
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
BlastWave



Joined: 05 Oct 2006
Posts: 6
BlastWave 06 Oct 2006, 11:07
no i did
lea ecx,[temp + 13]
mov dword[temp + 1024],ecx

and it work but i don't understand why i should use the size of the allocated.
Me just totaly confused now.
Post 06 Oct 2006, 11:07
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 06 Oct 2006, 11:18
here is my substring function from FASMLIB. It is quite long, but very tested and works in all cases that came to my mind. It is protected from overflows by always requiring max buffer length for every string - this also causes most "hard" cases. Specifically, how to beheave when there is no termination zero in entire buffer. I will document this more deeply in FASMLIB later.

Code:
;===============================================================================================
; str.sub
; desc: extract substring from string
; args: dest    - destination string buffer
;       destlen - destination string buffer length
;       src     - source string pointer
;       srclen  - source string buffer length
;       index   - index in string from where we start extracting
;       len     - number of characters to take into new string
; ret: CF set on error, otherwise
;      EAX = dest (for use with nested libcalls), and
;      OF set if index+len is behind source string (eg. dest string contains less than len chars)
; error: ERR_OUT_OF_RANGE - index is higher than length of string (or length of buffer)
;        ERR_ZERO_SIZE - destlen=0 or srclen=0 or len=0
;        ERR_BUFFER_FULL - destination buffer not long enough. in this case only first destlen chars
;                          are copied, and dest buffer is not terminated by zero
;        +str.len
;        +mem.copy
;===============================================================================================
proc str.sub, dest, destlen, src, srclen, index, len
        push    ecx esi
        pushf
        cld

        ;error if destlen=0
        cmp     [destlen], 0
        je      .error_destlen_zero

        ;error if srclen=0
        cmp     [srclen], 0
        je      .error_srclen_zero

        ;error if len=0
        cmp     [len],0
        je      .error_len_zero

        ;ECX = length of source string
        libcall str.len, [src], [srclen]
        jc      .rc
        mov     ecx, eax

        ;ERR_OUT_OF_RANGE if index >= length of source string
        cmp     [index], ecx
        jae     .error_index_out_of_range

        ;ECX = required length for the new string = min(index+len, str.len(string)) - index
        mov     eax, [index]
        add     eax, [len]
        cmp     eax, ecx
        jbe     @f
        mov     eax, ecx
        or      word [esp], 1 shl 11 ;set OF
@@:
        sub     eax, [index]
        mov     ecx, eax

        ;ECX = length in dest buffer = min(ECX, destlen)
        mov     eax, [destlen]
        cmp     ecx, eax
        cmova   ecx, eax

        ;get position in source string from where to copy
        mov     esi, [src]
        add     esi, [index]

        ;copy actual part of string that should be copied
        libcall mem.copy, [dest], esi, ecx
        jc      .rc

        ;error if there is no place for ending zero, eg. if ECX = destlen
        cmp     ecx, [destlen]
        je      .error_dest_buffer_full

        ;otherwise add ending zero
        add     ecx, [dest]
        mov     byte [ecx], 0

        ;return dest
        mov     eax, [dest]

.rnc:   and     byte [esp], not 1 ;clear CF
.r:     popf
        pop     esi ecx
        ret
.rc:    or      byte [esp], 1 ;set CF
        jmp     .r

.error_dest_buffer_full:
        mov     eax, ERR_BUFFER_FULL
        jmp     .rc

.error_destlen_zero:
        mov     eax, ERR_ZERO_SIZE
        jmp     .rc

.error_srclen_zero:
        mov     eax, ERR_ZERO_SIZE
        jmp     .rc

.error_len_zero:
        mov     eax, ERR_ZERO_SIZE
        jmp     .rc

.error_index_out_of_range:
        mov     eax, ERR_OUT_OF_RANGE
        jmp     .rc

endp    


requires few more things to run (ERR_ symbols, str.len, mem.copy), but idea is there. If someone wants to utilize this in his code, contact me then
Post 06 Oct 2006, 11:18
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Oct 2006, 12:31
Did you called "stdcall mid,text,temp,10 " or "stdcall mid,[text],[temp],10 "? With the first you are indicating to mid to work on the pointers while the second one indicates to mid to work on the strings pointed by the pointers. Note that in this case text and temp are pointers and not the labels with reserved or initialized data.

And yes, note that my PROC is buggy, I'm not taking into account the possibility of a index greater than the index of the NULL character so the idea of Goplat can't be used Razz

PD: I don't know what are you doing with that LEA on the MessageBox part but you probably have the same error passing temp parameter, it should be [temp].
Post 06 Oct 2006, 12:31
View user's profile Send private message Reply with quote
BlastWave



Joined: 05 Oct 2006
Posts: 6
BlastWave 06 Oct 2006, 22:08
@locodelassembly
I've try both still not working, im not familiar with the way assembler want me to control pointers so i always try lot diffence ways. I know its noobish.

@vid
Ty looks very intersting, just not too familiar with the instructions the 86x gives, any got some good reference? the only one i got the comment is
Test, Test a register.

lol not help much with that kinda comment.
Post 06 Oct 2006, 22:08
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.