flat assembler
Message board for the users of flat assembler.

Index > Windows > String functions

Goto page Previous  1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 05 Feb 2013, 20:34
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 1 time in total
Post 05 Feb 2013, 20:34
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 05 Feb 2013, 21:38
f0dder,

They're nowhere near safe place (unless they're heavily guarded). strcat() vs. strncat(), that's just about carelessness.

OTOH, delimited strings are good to train brain (and CPU) in pattern recognition (in general).
Post 05 Feb 2013, 21:38
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 05 Feb 2013, 21:53
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 1 time in total
Post 05 Feb 2013, 21:53
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1635
Location: Toronto, Canada
AsmGuru62 05 Feb 2013, 21:57
Of course all replacements are done in place.
No need for any memory allocations.
Post 05 Feb 2013, 21:57
View user's profile Send private message Send e-mail Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 21:59
AsmGuru62,
AsmGuru62 wrote:
Of course all replacements are done in place.
No need for any memory allocations.

Maybe I don't understand something. But when you've code like below:
Code:
Text db "Some text...",0
Title db "Title",0    
How can you replace "e" for "XXX" in Text without changing a pice of Title?


I downloaded and installed MASM. Also I've found szReplac and I begin to translate MASM -> FASM, but I've little problems with it.

Can you take a look, please?
Code:
proc szRep src:DWORD,dst:DWORD,txt1:DWORD,txt2:DWORD

    local lsrc:DWORD

    push ebx
    push esi
    push edi

    mov lsrc, len(src)          ; procedure call for src length
    sub lsrc, len(txt1)         ; procedure call for 1st text length

    mov esi, src
    add lsrc, esi               ; set exit condition
    mov ebx, txt1
    add lsrc, 1                 ; adjust to get last character
    mov edi, dst
    sub esi, 1
    jmp rpst
  ; ----------------------------
  align 4
  pre:
    add esi, ecx                ; ecx = len of txt1, add it to ESI for next read
  align 4
  rpst:
    add esi, 1
    cmp lsrc, esi               ; test for exit condition
    jle rpout
    movzx eax, BYTE PTR [esi]   ; load byte from source
    cmp al, [ebx]               ; test it against 1st character in txt1
    je test_match
    mov [edi], al               ; write byte to destination
    add edi, 1
    jmp rpst
  ; ----------------------------
  align 4
  test_match:
    mov ecx, -1                 ; clear ECX to use as index
    mov edx, ebx                ; load txt1 address into EDX
  @@:
    add ecx, 1
    movzx eax, BYTE PTR [edx]
    test eax, eax               ; if you have got to the zero
    jz change_text              ; replace the text in the destination
    add edx, 1
    cmp [esi+ecx], al           ; keep testing character matches
    je @B
    movzx eax, BYTE PTR [esi]   ; if text does not match
    mov [edi], al               ; write byte at ESI to destination
    add edi, 1
    jmp rpst
  ; ----------------------------
  align 4
  change_text:                  ; write txt2 to location of txt1 in destination
    mov edx, txt2
    sub ecx, 1
  @@:
    movzx eax, BYTE PTR [edx]
    test eax, eax
    jz pre
    add edx, 1
    mov [edi], al
    add edi, 1
    jmp @B
  ; ----------------------------
  align 4
  rpout:                        ; write any last bytes and terminator
    mov ecx, -1
  @@:
    add ecx, 1
    movzx eax, BYTE PTR [esi+ecx]
    mov [edi+ecx], al
    test eax, eax
    jnz @B

    pop edi
    pop esi
    pop ebx

    ret

endp     

I don't see any memory allocations. Hmm... it's odd.


Last edited by Kazyaka on 05 Feb 2013, 22:09; edited 1 time in total
Post 05 Feb 2013, 21:59
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 05 Feb 2013, 22:07
HaHaAnonymous wrote:
I don't think so. You can learn a lot by doing that (if you do it from a scratch).
I second that. Those SIMD routines for strlen() are quite entertaining reading, at least. Wink


----8<----
Kazyaka,

Those function-like len(src) will be a problem. And movzx eax,.../cmp al,... sequence looks strange.
Post 05 Feb 2013, 22:07
View user's profile Send private message Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 22:14
baldr,
baldr wrote:
Those function-like len(src) will be a problem. And movzx eax,.../cmp al,... sequence looks strange.
Heh. So not only I've problem with this. We can skip len(src), but I don't know how about movzx eax,.../cmp al,...
Post 05 Feb 2013, 22:14
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 05 Feb 2013, 22:17
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 2 times in total
Post 05 Feb 2013, 22:17
View user's profile Send private message Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 22:25
HaHaAnonymous,

I totally agree with your statement.
HaHaAnonymous wrote:
text db "Some text...",$00..$00...$00 till the size you want.
That's right, but when I want to use it in run-time and I don't know the size of replaced string, I must allocate the memory.
Post 05 Feb 2013, 22:25
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 05 Feb 2013, 22:47
HaHaAnonymous wrote:
Quote:

Re-creating libc style functions is just madness

I don't think so. You can learn a lot by doing that (if you do it from a scratch).

With the advantage to know exactly how the functions will work in any case. This can prevent a lot of bugs.

Oh, you can learn from the ordeal, and that can be a valuable experience - but it's not a good idea using libc-style functions in production code, as they're inherently unsafe... unless you never deal with user input.

You can get safer AND faster code by moving to length-prefixed strings and string manipulation functions with a saner interface.

_________________
Image - carpe noctem
Post 05 Feb 2013, 22:47
View user's profile Send private message Visit poster's website Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 05 Feb 2013, 23:04
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 1 time in total
Post 05 Feb 2013, 23:04
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 05 Feb 2013, 23:10
The unsafety of the libc string routines have been discussed to death elsewhere - too lazy to find references, but it shouldn't be hard. Bottom line is that it's not something you can fix with code, it's inherent from the routine interfaces.

If you don't care about malicious users being able to crash your software and possibly do remote-code-execution, sure - stick with libc interface. I just don't understand why people cling on to it, when you can have safer and faster by choosing something else.
Post 05 Feb 2013, 23:10
View user's profile Send private message Visit poster's website Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 05 Feb 2013, 23:39
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 1 time in total
Post 05 Feb 2013, 23:39
View user's profile Send private message Reply with quote
ASM-Man



Joined: 11 Jan 2013
Posts: 64
ASM-Man 06 Feb 2013, 00:35
You should think on preserve the registers. What about you are in routine that use eax but you have performed a call routine with a ret and when the calling-routine ends its job,the below instructions (or below,if you make a jump to a label above) that continues running - is expecting for such eax-value which was modified by your calling-routine? in a considerable lines of assembly code it's very bad. Of course that some routines will change registers but is only them which you won't preserve. A when it happens,put it on funtion/routine-descreption.

As already been mentioned,is a good pratice you comment the code. It will help yourself and another programmers to understand it.
I think that you like man-page(from UNIX) model? it's simple,I use something like this:

DESCRIPITION:
this function take as parameters EAX and EBX do X,Y and Z.

INPUT:
EAX = ..
EBX = ..

OUTPUT:
EAX =

NOTE: (if any)

BUGS:(if any)
Post 06 Feb 2013, 00:35
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 12856
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 0010456
sleepsleep 06 Feb 2013, 02:15
vid got a complete string function implementation,
http://fasmlib.x86asm.net/
Post 06 Feb 2013, 02:15
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1391
Location: Piraeus, Greece
Picnic 06 Feb 2013, 07:15
Kazyaka wrote:

I downloaded and installed MASM. Also I've found szReplac and I begin to translate MASM -> FASM, but I've little problems with it.

Can you take a look, please?

I don't see any memory allocations. Hmm... it's odd.


Hi Kazyaka,

I made few quick changes, it should be more clear now.
Memory allocation must be made outside the function, i guess somehow you have to calculate first how much space lpDst will need.
ps. I did not bother to see how it works.

Code:
proc szRep lpSrc:DWORD, lpDst:DWORD, lpszSearchFor:DWORD, lpszReplaceWith:DWORD

    local lsrc:DWORD 

    push ebx 
    push esi 
    push edi 

;   mov lsrc, len(src)           ; procedure call for src length
;   sub lsrc, len(txt1)          ; procedure call for 1st text length

    invoke lstrlen, [lpSrc]
    mov [lsrc], eax
    invoke lstrlen, [lpszSearchFor]
    sub [lsrc], eax

    mov esi, [lpSrc]
    add [lsrc], esi              ; set exit condition
    mov ebx, [lpszSearchFor]
    add [lsrc], 1                ; adjust to get last character
    mov edi, [lpDst]
    sub esi, 1 
    jmp rpst 
  ; ---------------------------- 
  align 4 
  pre: 
    add esi, ecx                ; ecx = len of lpszSearchFor, add it to ESI for next read
  align 4 
  rpst: 
    add esi, 1 
    cmp [lsrc], esi             ; test for exit condition
    jle rpout 
    movzx eax, BYTE PTR [esi]   ; load byte from source 
    cmp al, [ebx]               ; test it against 1st character in lpszSearchFor
    je test_match 
    mov [edi], al               ; write byte to destination 
    add edi, 1 
    jmp rpst 
  ; ---------------------------- 
  align 4 
  test_match: 
    mov ecx, -1                 ; clear ECX to use as index 
    mov edx, ebx                ; load lpszSearchFor address into EDX
  @@: 
    add ecx, 1 
    movzx eax, BYTE PTR [edx] 
    test eax, eax               ; if you have got to the zero 
    jz change_text              ; replace the text in the destination 
    add edx, 1 
    cmp [esi+ecx], al           ; keep testing character matches 
    je @B 
    movzx eax, BYTE PTR [esi]   ; if text does not match 
    mov [edi], al               ; write byte at ESI to destination 
    add edi, 1 
    jmp rpst 
  ; ---------------------------- 
  align 4 
  change_text:                  ; write lpszReplaceWith to location of lpszSearchFor in destination
    mov edx, [lpszReplaceWith]
    sub ecx, 1 
  @@: 
    movzx eax, BYTE PTR [edx] 
    test eax, eax 
    jz pre 
    add edx, 1 
    mov [edi], al 
    add edi, 1 
    jmp @B 
  ; ---------------------------- 
  align 4 
  rpout:                        ; write any last bytes and terminator 
    mov ecx, -1 
  @@: 
    add ecx, 1 
    movzx eax, BYTE PTR [esi+ecx] 
    mov [edi+ecx], al 
    test eax, eax 
    jnz @B 

    pop edi 
    pop esi 
    pop ebx 

    ret 

endp               
    
Post 06 Feb 2013, 07:15
View user's profile Send private message Visit poster's website Reply with quote
Asm++



Joined: 04 Feb 2013
Posts: 24
Location: On a Chip!
Asm++ 06 Feb 2013, 07:25
Kazyaka,
Hi, I have a little question about StringCopy(pSrc, pDest, dwBytes),

Why do we need dwBytes parameter? Question

_________________
Binary is nice, but Assembly is better!
Post 06 Feb 2013, 07:25
View user's profile Send private message Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 06 Feb 2013, 09:55
sleepsleep,
sleepsleep wrote:
vid got a complete string function implementation,
http://fasmlib.x86asm.net/
I know about this, but I didn't find string replacement function there.

Picnic,

Also I changed "BYTE PTR" for "byte" in your code, but it still doesn't work.

Asm++,
Asm++ wrote:
Hi, I have a little question about StringCopy(pSrc, pDest, dwBytes),
Why do we need dwBytes parameter? Question
You've text "Welcome to the site of flat assembler!", and you want to copy only first word to some other place. Will you copy all bytes? Of course, not. So you must use 7 in this case as the third parameter.
Post 06 Feb 2013, 09:55
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1391
Location: Piraeus, Greece
Picnic 06 Feb 2013, 10:09
[b]Kazyaka[b] are you sure, did you also add all those brackets?
Here, do a quick lame test, works for me.

Code:
format pe console 4.0

include "win32axp.inc"

PTR equ

.data
        source db "This is a kind of text. This kind is a big fat kind",0
        dest rb 256
        search db "kind",0
        replace db "line",0

.code
main:
        stdcall szRep, source, dest, search, replace
        invoke MessageBox, 0, dest, "", 0
        ret


; place the proc i posted here.
;


.end main     


Last edited by Picnic on 06 Feb 2013, 10:22; edited 1 time in total
Post 06 Feb 2013, 10:09
View user's profile Send private message Visit poster's website Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 06 Feb 2013, 10:22
My mistake. I probably put parameters in a wrong piece of code.
But I can't see sense of this line:
Code:
PTR equ    
I think we can just replace all "BYTE PTR" with "byte", right?

Thanks for translate from MASM to FASM.
Post 06 Feb 2013, 10:22
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4  Next

< 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.