News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Reverse string

Started by lostcauz, October 01, 2005, 05:19:45 PM

Previous topic - Next topic

Jimg

Ok, I was using the first lostcauz post as the basis which copied from one buffer to another.

Jimg

You're absolutely right.  Writing back to the same buffer when it is not a multiple of 4 bytes incurs a large time penalty.

NightWare

jimg,

maybe i should been more explicit... the problem doesn't appear during the assembling, it crash when i launch the assembled code, here a copy of the screen when it crash
(maybe i've an unupdated .inc file...  :'( unfortunatelly i haven't enought time to see what's wrong here...)


Str1 Size        1     9    18    27    28    29    36   100   400  1000
============ ===== ===== ===== ===== ===== ===== ===== ===== ===== =====

0 byte misalignment
OVH


now, return of the son of the son of the algo...  :bdg

it's short, it's fast (i think it will be very difficult to make a faster code than the following algo... i speak about "ReverseString algo", i don't speak about "IVeCreatedAnotherStringInReverseOrderNowYouJustHaveToCopyItOverTheOriginal algo"  :wink )

don't try to understand the code, if you want to keep your mind safe...  :dazzled: there is already a victim  :toothy , we don't need another one... just use it (if you need it)

FastReverseString -> UltimateReverseString => ebx is not used anymore, a smart mini-shift is used to avoid lot of instructions (i'm a genius, sometimes...  :U )


ALIGN 16
UltimateStringReverse PROC StrAddr:DWORD,StrSize:DWORD
push esi
push edi

mov esi,StrAddr
mov eax,StrSize
lea edi,[esi+eax-2]
shr eax,1
sub edi,eax
add eax,-2
js Label2
Label1: mov ecx,DWORD PTR [esi]
mov edx,DWORD PTR [edi+eax]
bswap ecx
bswap edx
mov DWORD PTR [edi+eax],ecx
mov DWORD PTR [esi],edx
add esi,4
add eax,-4
jns Label1
Label2: cmp eax,-1
jne Label3
mov cl,BYTE PTR [edi+2]
mov ch,BYTE PTR [esi]
mov BYTE PTR [edi+2],ch
mov BYTE PTR [esi],cl
Label3:
pop edi
pop esi
ret
UltimateStringReverse ENDP


Ratch

NightWare,
     I tested UltimateStringReverse, and it reverses a string correctly.  When I compared its time to my routine by reversing the alphabet 100,000,000 times, it took around 6 seconds to do that on my machine.  That is the same time that my routine takes.  I don't see anything in your main loop that is significantly different from the way your previous submissions, my submissions, and other submissions do things in the main loop.  They pick up a DWORD from one end of the string and put it down at the other end.  Therefore the times should be about the same.  If you want to really speed thing up, you can write the output to a different buffer like Lingo does, so as to avoid cache collisions.  But then the string is not reversed in place is it?  Ratch

Jimg

Nightware-

Quotejimg,

maybe i should been more explicit... the problem doesn't appear during the assembling, it crash when i launch the assembled code, here a copy of the screen when it crash

Please try this code and let me know what is printed out in the debug window.  Thanks.

[attachment deleted by admin]

NightWare

Ratch,
Quote from: Ratch on October 16, 2005, 01:54:28 AM
If you want to really speed thing up, you can write the output to a different buffer like Lingo does, so as to avoid cache collisions.  But then the string is not reversed in place is it?  Ratch

our code are faster than you imagine... if you want a speed-up you can use a direct esp read, in the beginning... (nice speedup for me)...

but most important of all... with our code we don't need to reserve an empty space, we don't need to free this space after a use, etc... all these facts are not counted in the speed test...

jimg,

HARG ! i've said i haven't enought time.... damn... well, ok...

then i try to assemble the new code => fatal error, unable to find kernel32.lib ??? i don't understand, of course, i look inside the lib dir, and you know what ? it's in... so i spend some time to see what's wrong (coz all paths are correct), and i don't find... so i decide to see the difference with your old code... => debug.lib
ok, so i change your uselib macro to a classic includelib (coz i don't have a debug.inc file) and then it pass the kernel32.lib error (if you ask me, debug is bugged)

BUT ! (there is always a "but") i have 5 or 6 errors with PrintText (it seams it's one of your macros). so i transform it to old print... so i hope the result is fine on the screen, since i don't know if your routine add something or not...

here a copy of the screen when it crash :

Str1 Size      1
=========== ====

0 byte misalignment
starting procsloopOVH        moving proccreating stringcreating answer



Jimg

Ok, never mind.  Let me know if you ever want to figure out the problem.

OS

#67
Hey all it's been a loooong while,firstly I just want to say hi again and I did
miss everyone.

Anyhow I have been getting into ASM again and was reading the board
and saw this problem. I was wondering if this was a viable solution, It's what
I use.
GOASM format should be easy to convert if anyone cares to.

ReverseString frame LpSrc,LpBuffer

; Will reverse a standard
; size string , ADDR PTR
; returns in eax. LpBuffer
; is the string buffer
; yet EAX will hold the
; strings starting addr.
mov  eax,[LpBuffer] ; {move the values to registers.
mov  ecx,[LpSrc] ; {
mov  B[eax+0100h],00h ; Null terminate the string
add  eax,0100h ; Get ready to climb down the buffer
sub  eax,01h ; dec the buffer
mov  dl,[ecx] ; {
mov  [eax],dl ; {buffer byte=src byte
add  ecx,01h ; inc ECX
cmp  B[ecx],00h ; did we finish?
db 74h,02h ; JZ   @F
db EBh,EFh ; JMP  @B @@:

ret
endf



This way you still use the buffer you just don't have the buffers starting address .
It returns in EAX .
-OS

*Edit used the wrong version the old version copied the trailing zero.