flat assembler
Message board for the users of flat assembler.

Index > Windows > String functions

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



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 12:17
I want to put all string manipulation functions in the one place, because I'm bored of searching some of them every time.

Here's my list. I found these functions in FASM Forum and little modified them. All work with null-terminated strings.

IntToStr(dwNumber, pBuffer)
Converts integer (doesn't allow negative and float numbers) to string.

StringCopy(pSrc, pDest, dwBytes)
Copies a string of characters from the first to the second string.

StringLen(pString)
Returns lenght of the string.

StringCmpCS(pString1, pString2)
Compares two strings (case sensitivity). If the function succeeds, the return value is the number of compared bytes. Else if the function fails, the return value is zero.
Code:
IntToStr:
mov eax,[esp+4]
mov edi,[esp+8]
mov ecx,10
.stack_dec:
xor edx,edx
div ecx
add edx,'0'
push edx
test eax,eax
jz .purge_dec
call .stack_dec
.purge_dec:
pop dword[edi]
inc edi
ret

StringCopy:
mov esi,[esp+4]
mov edi,[esp+8]
mov ecx,[esp+12]
rep movsb
ret

StringLen:
mov edi,[esp+4]
mov eax,-1
@@:
inc eax
cmp byte [edi+eax],0
jnz @b
ret

StringCmpCS:
mov ecx,[esp+4]
mov edx,[esp+8]
.loop:
mov al,[ecx]
cmp al,[edx]
jne .no_match
add ecx,1
add edx,1
test al,al
jne .loop
mov eax,1
jmp .match
.no_match:
xor eax,eax
.match:
ret    

I tested all and they work correctly.

I'm still looking for:
- StringFind
- StringReplace
- StringReplaceFirst

If you have some of them or other interesting functions then feel free to post them. I'll update the thread.


Last edited by Kazyaka on 05 Feb 2013, 12:24; edited 1 time in total
Post 05 Feb 2013, 12:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 05 Feb 2013, 12:23
Can we assume you use ccall convention? Edit: No wait, you didn't seen to use any convention that I can tell. You destroy registers seemingly randomly. Wink

Also, you posted in the Windows section and some of those function are already provided by the Windows API.
Post 05 Feb 2013, 12:23
View user's profile Send private message Visit poster's website Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 12:29
I'm using stdcall to call the procedures.

Here's a pice of my code:
Code:
...
stdcall StringCopy,[SymbolStart],[SymbolBuffer],[SymbolLenght]
;Checks if first string is keyword
stdcall StringCmpCS,[SymbolBuffer],"Hello"
...    
Is it wrong?
Post 05 Feb 2013, 12:29
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 05 Feb 2013, 12:36
Kazyaka wrote:
I'm using stdcall to call the procedures.

Here's a pice of my code:
Code:
...
stdcall StringCopy,[SymbolStart],[SymbolBuffer],[SymbolLenght]
;Checks if first string is keyword
stdcall StringCmpCS,[SymbolBuffer],"Hello"
...    
Is it wrong?
Yes, this is wrong because your functions do not conform to stdcall convention. You must return results in EAX and preserve ESI, EDI, EBP and EBX. Plus you will need to pop the input parameters off the stack upon return (e.g. ret 4).
Post 05 Feb 2013, 12:36
View user's profile Send private message Visit poster's website Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 12:47
Thanks for note. I'm beginner FASM programmer and I didn't know about this. You mean that I should use proc/endp macros, right? But what if it works fine with wrong construction, I have to use it? Or maybe is some other way to correctly call my procedures without changing them?
Post 05 Feb 2013, 12:47
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 05 Feb 2013, 13:32
You don't have to use proc/endp, they are only for convenience, you can do it manually if you want to.

Also, it won't work fine with the wrong construction in all cases. There are some situations where they will work but don't expect it all to be fine when using stdcall as you caller. Your test code is probably not worried about stack or register preservation so it won't show a problem for you until you start using it in a real program.

I would suggest you change the functions to conform with your caller function. It is less confusing and easier to integrate into other code.
Post 05 Feb 2013, 13:32
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 05 Feb 2013, 14:04
Kazyaka, I am sure, you want to see FreshLib/data/strlib.asm library. It is full of string functions. Although, this library uses slightly different string format in order to provide dynamically sized strings.
Post 05 Feb 2013, 14:04
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Kazyaka



Joined: 10 Oct 2011
Posts: 62
Location: Earth
Kazyaka 05 Feb 2013, 14:41
revolution,

Quote:
You don't have to use proc/endp, they are only for convenience, you can do it manually if you want to.

Doing it manually only impedes the work. So if I've to change my procedures I'd to use proc/endp macros.

Quote:
Also, it won't work fine with the wrong construction in all cases. There are some situations where they will work but don't expect it all to be fine when using stdcall as you caller. Your test code is probably not worried about stack or register preservation so it won't show a problem for you until you start using it in a real program.

That's right. It explains some odd bugs. Now I can see sense of following your way.

Quote:

I would suggest you change the functions to conform with your caller function. It is less confusing and easier to integrate into other code.


Like this?
Code:
include 'win32ax.inc'

.code

  start:

        stdcall StringCopy,text,empty,5
        invoke  MessageBox,HWND_DESKTOP,empty,"Title",MB_OK
        invoke  ExitProcess,0

  proc StringCopy uses esi edi ecx,str1,str2,len
  mov esi,[str1]
  mov edi,[str2]
  mov ecx,[len]
  rep movsb
  ret
  endp

.end start

text db "Hello, my Friend!",0
empty rb 10    

Please say me, if something's wrong.

JohnFound,

I already have FreshLib on my computer (I downloaded it 2 days ago), but it's easier to read when all string manipulation functions are on the one side. So thanks.
However I still can't find "StringReplace" procedure.
Post 05 Feb 2013, 14:41
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 05 Feb 2013, 14:50
Kazyaka wrote:
Like this?
Code:
include 'win32ax.inc'

.code

  start:

        stdcall StringCopy,text,empty,5
        invoke  MessageBox,HWND_DESKTOP,empty,"Title",MB_OK
        invoke  ExitProcess,0

  proc StringCopy uses esi edi ecx,str1,str2,len
  mov esi,[str1]
  mov edi,[str2]
  mov ecx,[len]
  rep movsb
  ret
  endp

.end start

text db "Hello, my Friend!",0
empty rb 10    
Yes, like that. Note that preserving ecx is not required (not harmful either, just not necessary).

Also it might be a good idea to always ensure you return a zero terminated string. Your "empty" display only works because the previous storage at that location had a zero byte in the sixth position. In many real programs you can't always be sure what the next byte will be so placing an explicit zero byte is generally a good idea.
Post 05 Feb 2013, 14:50
View user's profile Send private message Visit poster's website Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1637
Location: Toronto, Canada
AsmGuru62 05 Feb 2013, 15:22
There is no need for any conventions in ASM -- they are needed only for CALLBACK functions in Win API.
If you design your own string functions - you can do whatever you wish.
Just describe in a function header what exactly your function does and how it
accepts parameters and returns results.
I have a function like this one in my library:
Code:
Lib_StrCopy:
; -----------------------------------------------------------------
; INPUT:
;       ESI = source string
;       EDI = destination buffer
; OUTPUT:
;       EDI = points to a NULL terminator in destination buffer
; -----------------------------------------------------------------
        ...
        ret
    

I use it to concatenate text.
That is why ASM allows for great coding freedom.
Post 05 Feb 2013, 15:22
View user's profile Send private message Send e-mail Reply with quote
HaHaAnonymous



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


Last edited by HaHaAnonymous on 28 Feb 2015, 21:42; edited 1 time in total
Post 05 Feb 2013, 15:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 05 Feb 2013, 15:31
AsmGuru62 & HaHaAnonymous: Yes, of course you can use whatever calling format you please but the OP here stated they were using stdcall so there was clearly a problem. I only suggested to change the function to conform, an alternative could have been to simply change the caller to agree with the functions.

However not using any standard (whether stdcall, ccall or some other private standard) can get very confusing for larger programs. It is up to the programmer how they wish to do call/ret, but consideration should be given to potential bug reduction at a small cost in size/speed. Often spending days chasing an obscure bug easily loses to using more uniform call/ret procedures.
Post 05 Feb 2013, 15:31
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 05 Feb 2013, 15:46
AsmGuru62 wrote:
There is no need for any conventions in ASM -- they are needed only for CALLBACK functions in Win API.

almost true - if you STD, you'll need to CLD calling APIs, you'll need to make sure the stack is aligned (and within the limits set by [fs:whatever]), and probably a couple of other things as well...

but sure, you're free to wildly trash registers in your own code, as long as it's not callback... whether it's a good idea is an open question Smile

_________________
Image - carpe noctem
Post 05 Feb 2013, 15:46
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, 15:51
[ Post removed by author. ]


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



Joined: 05 May 2007
Posts: 1391
Location: Piraeus, Greece
Picnic 05 Feb 2013, 17:19
Kazyaka wrote:
However I still can't find "StringReplace" procedure.


Idea See szRep (szreplac.asm) inside masm32 package, it should be fairly easy to use in fasm.
Post 05 Feb 2013, 17:19
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, 17:31
[ Post removed by author. ]


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



Joined: 28 Jan 2004
Posts: 1637
Location: Toronto, Canada
AsmGuru62 05 Feb 2013, 17:47
String replacement is fun to code -- especially with some weirdo testing code, like:
1. Replace "AA" in "123-AAAAAAAAAAAA-456" with "AAA".
2. Replace "AAAA" in "123-AAAAAAAAAAAA-456" with "A".
Post 05 Feb 2013, 17:47
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, 19:59
How many replies... you took over the thread. It's an invasion!

I don't know where to start, so I begin from the end.

AsmGuru62,
AsmGuru62 wrote:
String replacement is fun to code -- especially with some weirdo testing code, like:
1. Replace "AA" in "123-AAAAAAAAAAAA-456" with "AAA".
2. Replace "AAAA" in "123-AAAAAAAAAAAA-456" with "A".

I don't understand. Do you think, it will loop infinitely at the first case and remove all "A" characters at the second, or what? In my point of view, it's just a normal code.
The correctly working functions should return:
Code:
1. "123-AAAAAAAAAAAAAAAAAA-456" 
2. "123-AAA-456"    

HaHaAnonymous,

It's not as easy as you think (for me). If you want to replace string as in the first case above, you must use some memory management functions like GlobalAlloc or HeapAlloc, because the size of replaced string can be much more then before function call. It only complicates matters.

Picnic,
Picnic wrote:
Idea See szRep (szreplac.asm) inside masm32 package, it should be fairly easy to use in fasm.

Thanks for information. I'm going to check it for a while.

@To all:
I see that your opinions are divided. So I've a question: can I use functions from the first post with a clear conscience, or not?

By the way, thank you all for your replies. You're making this word better!
Post 05 Feb 2013, 19:59
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 05 Feb 2013, 20:06
Kazyaka wrote:
How many replies... you took over the thread. It's an invasion!
Treat it with antibiotics, unless it's viral. Wink

Guys, don't you think that delimited arbitrary length strings should be banned from existense in favor of counted strings? Delphi style looks intimidating. Wink
Post 05 Feb 2013, 20:06
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 05 Feb 2013, 20:26
baldr wrote:
Guys, don't you think that delimited arbitrary length strings should be banned from existense in favor of counted strings?

Indeed - length-counted strings are both faster as well as safer to work with. Re-creating libc style functions is just madness Smile

_________________
Image - carpe noctem
Post 05 Feb 2013, 20:26
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 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.