flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Fun with someone's strcat

Author
Thread Post new topic Reply to topic
Fred



Joined: 22 Oct 2010
Posts: 39
Fred 07 Nov 2010, 04:46
Someone here on this forum came up with some strcat proc, so I grabbed it and made it into a macro for unicode strings instead.

Code:
macro strcatW dest,src{
local .get_str_len,.store_str

    pusha
    mov esi,dest
    mov edx,-2

.get_str_len:
    lodsw
    add edx,2
    test ax,ax ;test al,al ;cmp al,0
    jne .get_str_len

    mov esi,src
    mov edi,dest
    add edi,edx

.store_str:
    lodsw
    stosw
    test ax,ax
    jnz .store_str
  
    popa}    

One thing i'm not sure about is "cmp al,0". I changed this to ax because unicode strings uses two bytes, but I'm not sure if my logic holds up (pretty new to asm). Not sure which one of cmp and test is better in this case, just trying out different things mostly.

Anyway, not satisfied with the low haxxor techniques required for that, I tried to play around some. (also, I just found out about movs.)

Code:
macro strcatW2 dest,src{
local .get_str_len

    mov esi,dest
    mov ecx,-2

.get_str_len:
    lodsw
    add ecx,2
    test ax,ax
    jne .get_str_len

    mov esi,src
    mov edi,dest
    add edi,ecx
    rep movsw}    

(pusha/popa was removed since i didn't need them inside the macro)
Rad! It works! But I wanted to play around a little more, now that I'm starting to get the hang of basic asm.

Code:
macro strcatW3 dest,src{
local .get_str_len

    mov edi,dest
    mov esi,src
    mov ecx,-2 ;is _e_cx needed/does it matter?

.get_str_len:
    test di,di
    inc di
    add ecx,2
    ;test di,di   ;both these "test di,di" works, not sure if that is a good thing or not    
    jne .get_str_len

    rep movsw}    

It works... again! I'm almost impressed by myself.


I have no idea if my wrangling just made the code worse or not (lol), but it was fun to see that I could get it to work.
Hmm... so what was the point of the post? Err... well, maybe you guys can tell me if my reworking of the original code is totally messed up or not. Laughing


Edit: (Hmm, now that i think about it, this isn't really windows related... i think. Oops. I made the macro inside a windows program, so I just kinda posted it here.)
Post 07 Nov 2010, 04:46
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 07 Nov 2010, 13:11
Your use of ax instead of al is fine.

But your use of ecx as a counter for rep movsw should be counting elements, not bytes.

In your third code section you are not reading the string when trying to find the length, you only increment di (should be edi) until it reaches zero.
Post 07 Nov 2010, 13:11
View user's profile Send private message Visit poster's website Reply with quote
Fred



Joined: 22 Oct 2010
Posts: 39
Fred 07 Nov 2010, 15:10
Quote:
But your use of ecx as a counter for rep movsw should be counting elements, not bytes.

Could you explain it a little more in-depth? Very Happy
That's how the initial code was, except using edx.

Quote:
In your third code section you are not reading the string when trying to find the length, you only increment di (should be edi) until it reaches zero.

Yes, you're right - it actually doesn't work. Bah... I'm sure I tested it yesterday... that's one downside with doing it at 04:30, I guess. Thanks for pointing out the errors, I'll try to fix it. Razz
Post 07 Nov 2010, 15:10
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 07 Nov 2010, 15:29
Code:
mov ecx,1
rep movsd ;move 4 bytes, one dword element

mov ecx,1
rep movsw ;move 2 bytes, one word element

mov ecx,1
rep movsb ;move 1 byte, one byte element    
Post 07 Nov 2010, 15:29
View user's profile Send private message Visit poster's website Reply with quote
Fred



Joined: 22 Oct 2010
Posts: 39
Fred 07 Nov 2010, 16:59
Yes, that makes sense.
Code:
macro strcatW dest,src{
local .get_str_len

    mov edi,dest
    mov esi,src
    mov ecx,-1

.get_str_len:
    mov eax,[edi]
    inc edi
    inc ecx
    test ax,ax
    jne .get_str_len

    rep movsw}      

This seems to work, but I can see that I don't understand it fully yet. Moving the data to eax works... for now, at least.
But something else is that I can put some random values into ecx and it will still work. Why's that?
Post 07 Nov 2010, 16:59
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 07 Nov 2010, 20:59
Try this:
Code:
macro strcatW dest,src{
local .get_str_len

    mov edi,dest
    mov esi,src
    mov ecx,-1 + 1 ;we need one more byte to copy the zero terminator also

.get_str_len:
    mov ax,[esi] ;word values only
    add esi,2 ;we read two bytes
    inc ecx ;add one element
    test ax,ax
    jne .get_str_len
    mov esi,src ;recover start address

.find_dest_pointer:
    mov ax,[edi] ;word values only
    add edi,2 ;we read two bytes
    test ax,ax
    jne .find_dest_pointer
    sub edi,2

    rep movsw}    
Post 07 Nov 2010, 20:59
View user's profile Send private message Visit poster's website Reply with quote
Fred



Joined: 22 Oct 2010
Posts: 39
Fred 07 Nov 2010, 22:32
Yeah, I looked through my code a little more in-depth today and saw what I tried to do and what I really did. I guess that means that I learned something. (POWER UP) Razz

Thanks for the code snippets and explanations.
Post 07 Nov 2010, 22:32
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 08 Nov 2010, 16:59
revolution wrote:
Code:
mov ecx,1
rep movsd ;move 4 bytes, one dword element

mov ecx,1
rep movsw ;move 2 bytes, one word element

mov ecx,1
rep movsb ;move 1 byte, one byte element    


Wait, what??? Just do this:

Code:
movsd ; move 4 bytes
movsw ; move 2 bytes
movsb ; move 1 byte
    


Very Happy
Post 08 Nov 2010, 16:59
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1614
Location: Ukraine
shoorick 09 Nov 2010, 06:41
another example:
Code:
macro _strcat dest,sour {
    mov edi,dest
    mov esi,sour
    mov ecx,-1
    xor eax,eax
    repne scasw ; searching zero word in first string
    sub edi,2 ; restore pointer to the zero at the and of the first string
.m:
    cmp word [esi],0 ; copy word by word same time comparing words with zero
    movsw
    jne .m ; to know when to stop
}
    
Post 09 Nov 2010, 06:41
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:  


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