flat assembler
Message board for the users of flat assembler.

Index > Windows > lstrcat replacement

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 05 Dec 2012, 20:34
Hello everyone ;)

Im trying to write a program in fasm and keep it as small as i can.

Does anyone know a lstrcat replacement. Because i dont want to imort the API unless there is no other way. I have found a replacement for lstrlen and it works perfect. Im just wondering if i can have that for lstrcat to?

many thanks before hand
Post 05 Dec 2012, 20:34
View user's profile Send private message MSN Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 05 Dec 2012, 20:42
To not steal from you the opportunity to do it the efficient way, I'll implement it in the laziest way possible, taking advantage of your lstrlen replacement:
Code:
proc lstrcat uses esi edi, lpString1, lpString2
  mov edi, [lpString1]
  stdcall lstrlen, edi

  add edi, eax

  mov esi, [lpString2]
  stdcall lstrlen, esi
 
  lea ecx, [eax + 1]
  rep movsb

  ret
endp    
Post 05 Dec 2012, 20:42
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 05 Dec 2012, 20:57
BTW, if you need full compatibility, you need to add "mov eax, [lpString1]" just before ret.
Post 05 Dec 2012, 20:57
View user's profile Send private message Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 05 Dec 2012, 20:59
LocoDelAssembly wrote:
To not steal from you the opportunity to do it the efficient way, I'll implement it in the laziest way possible, taking advantage of your lstrlen replacement:
Code:
proc lstrcat uses esi edi, lpString1, lpString2
  mov edi, [lpString1]
  stdcall lstrlen, edi

  add edi, eax

  mov esi, [lpString2]
  stdcall lstrlen, esi
 
  lea ecx, [eax + 1]
  rep movsb

  ret
endp    


Interesting.. thank you ill study this Wink
Post 05 Dec 2012, 20:59
View user's profile Send private message MSN Messenger Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler 05 Dec 2012, 22:40
jochenvnltn wrote:
Im trying to write a program in fasm and keep it as small as i can.


jochenvnltn wrote:
Does anyone know a lstrcat replacement. Because i dont want to imort the API unless there is no other way.


These statements are contradictory. Why not use StringCchCat?

_________________
This is a block of text that can be added to posts you make.
Post 05 Dec 2012, 22:40
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1660
Location: Toronto, Canada
AsmGuru62 05 Dec 2012, 22:42
Too many stdcall's!
Smile
Code:
;
; INPUT:
;   EDI = destination buffer
;   ESI = source buffer
; OUTPUT:
;   EAX = points to a null terminator in destination buffer
;   ( ^^^ in case of more concatenations to follow)
;
StrCat:
   push    ecx esi edi
 xor     eax, eax
    or      ecx, -1
     repne   scasb

   dec     edi

.more:
       lodsb
       stosb
       test    eax, eax
    jnz     .more

   lea     eax, [edi - 1]
      pop     edi esi ecx
 ret
    
Post 05 Dec 2012, 22:42
View user's profile Send private message Send e-mail Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 06 Dec 2012, 15:52
Dont know what to say.. Works perfect! This i will be using all the time!
You realy are a AsmGuru Wink

Code:
format pe gui 4.0
include 'win32ax.inc'

str1 db 'hello ',0
str2 db 'world!',0

dest dd ?

start:

        mov esi,str2
        mov edi,str1
        call StrCat

        invoke MessageBox,0,str1,'caption',MB_OK
        invoke ExitProcess,0

; StrCat Replacement
; fuck shit with Too many stdcall's!  By AsmGuru62 (.flatassembler.net)
; INPUT:
;   EDI = destination buffer
;   ESI = source buffer
; OUTPUT:
;   EAX = points to a null terminator in destination buffer
;   ( ^^^ in case of more concatenations to follow)
;
StrCat:

        push    ecx esi edi
        xor     eax, eax
        or      ecx, -1
        repne   scasb

        dec     edi

.more:
        lodsb
        stosb
        test    eax, eax
        jnz     .more

        lea     eax, [edi - 1]
        pop     edi esi ecx
        ret

.end start
    
Post 06 Dec 2012, 15:52
View user's profile Send private message MSN Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 06 Dec 2012, 16:12
jochenvnltn wrote:
Dont know what to say.. Works perfect! This i will be using all the time!
So, to avoid an import you're
1) adding more bytes to your executable and
2) (most likely) using a slower piece of code than the API version

_________________
Image - carpe noctem
Post 06 Dec 2012, 16:12
View user's profile Send private message Visit poster's website Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 06 Dec 2012, 17:06
Check this and change to without 'proc / endproc' if you want.


Description:
Download
Filename: STRING.INC
Filesize: 21.22 KB
Downloaded: 318 Time(s)

Post 06 Dec 2012, 17:06
View user's profile Send private message Send e-mail Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 06 Dec 2012, 17:51
marcinzabrze12 wrote:
Check this and change to without 'proc / endproc' if you want.


wow! thank you for this share! it looks very nice..
Post 06 Dec 2012, 17:51
View user's profile Send private message MSN Messenger Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 06 Dec 2012, 17:58
I just love this code snips! 1000x thank you!
Post 06 Dec 2012, 17:58
View user's profile Send private message MSN Messenger Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 06 Dec 2012, 18:52
Please report me if find some bug.
Post 06 Dec 2012, 18:52
View user's profile Send private message Send e-mail Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 06 Dec 2012, 22:16
marcinzabrze12 wrote:
Please report me if find some bug.


hello marcinzabrze12.. No! No bug's whatsoever.. Is you gmail in the source still valid? Ill use that to contact you then.. Agian.. thank you..
Post 06 Dec 2012, 22:16
View user's profile Send private message MSN Messenger Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 07 Dec 2012, 01:08
f0dder wrote:
jochenvnltn wrote:
Dont know what to say.. Works perfect! This i will be using all the time!
So, to avoid an import you're
1) adding more bytes to your executable and
2) (most likely) using a slower piece of code than the API version


Is (most likely) = Definitely? Because i needed this call multiple times in my code, so your gona say it's slower then the original API import? Im not an expert so please prove your point because im still learning .. and yes.. i have nothing better to do for now Smile
Post 07 Dec 2012, 01:08
View user's profile Send private message MSN Messenger Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 07 Dec 2012, 17:25
@f0dder:
Look at implementation of lstrcatA function (kernel32.dll) in AIDA.
lstrcatA is slower than ansiCat (from STRING.INC).
; -----------------------------------------------------------------

If yor code will work on Intel Core i5 or higher than you have specjal assembly instructions "PCMP(x)STR(y)" to do everything with a string data.
Post 07 Dec 2012, 17:25
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 08 Dec 2012, 04:59
f0dder wrote:
2) (most likely) using a slower piece of code than the API version
Are you sure? In general the APIs will be written to handle the average case reasonably efficiently. With "average" being defined by MS in an unknown way. I would doubt that the average case applies perfectly to everyone's usage. Plus the API will likely have extra generic overheads that a custom implementation might not need.
Post 08 Dec 2012, 04:59
View user's profile Send private message Visit poster's website Reply with quote
yoshimitsu



Joined: 07 Jul 2011
Posts: 96
yoshimitsu 08 Dec 2012, 19:14
The WinAPI version is implemented in the easiest way you can think of (loop and check for zero), it's actually pretty slow, but small (keeping kernel32.dll small).

Implementing your own function to save space is not really smart.
You're very likely already importing kernel32.dll's functions and adding lstrcat to them takes only a few bytes.

If you want speed and a small executable, you should import from msvcrt.dll instead.
These functions are optimized for speed and process multiple data at a time.
Post 08 Dec 2012, 19:14
View user's profile Send private message Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 09 Dec 2012, 00:37
Quote:
Implementing your own function to save space is not really smart

I don't need to save space. I need to improve speed.

Quote:
(loop and check for zero)

one JMP on every checked byte - what if you processing 500 KB text file ?
For this reason are instructions like movs* scas* ...

I looked now in AIDA disasembled code of msvcrt.dll "strlen", "strcmp" ... is not fast and is not that small.
Post 09 Dec 2012, 00:37
View user's profile Send private message Send e-mail Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1660
Location: Toronto, Canada
AsmGuru62 09 Dec 2012, 13:00
If your code has a lot of string concatenations you may want to think of developing
your own string library where you always know the string length, like Pascal does.
This way your concatenation code will omit the code searching for null terminator and
it will perform even faster.
Post 09 Dec 2012, 13:00
View user's profile Send private message Send e-mail Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 09 Dec 2012, 13:31
revolution wrote:
f0dder wrote:
2) (most likely) using a slower piece of code than the API version
Are you sure?
Nope, hence why I added the "(most likely)" part Smile. But you're right, took a look at kernel32, and it was pretty bad - basically two strlen loops and a memcpy (inline code blocks, not function calls, but still).

marcinzabrze12 wrote:
I don't need to save space. I need to improve speed.
Then you should neither use the Windows APIs nor any of the pieces of code posted in this thread so far Smile

marcinzabrze12 wrote:
I looked now in AIDA disasembled code of msvcrt.dll "strlen", "strcmp" ... is not fast and is not that small.
fast != small - often, fast ends up having a fair amount of code.

marcinzabrze12 wrote:
For this reason are instructions like movs* scas* ...
Which on some CPUs are quite a lot slower than manually unrolled loops that check several bytes at a time.

AsmGuru62 wrote:
If your code has a lot of string concatenations you may want to think of developing your own string library where you always know the string length, like Pascal does. This way your concatenation code will omit the code searching for null terminator and it will perform even faster.
+1.

And if you must deal with zero-terminated strings, I'd suggest at least moving to some safer routines than the libc ones... unless you absolutely, entirely and positively know what the input string lengths will be Smile
Post 09 Dec 2012, 13:31
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  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.