News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Cleaning the stack

Started by RuiLoureiro, December 18, 2016, 05:21:44 AM

Previous topic - Next topic

RuiLoureiro

Hi
    I need to clean tha stack used for variables (117000 bytes +/-).
    How to do it fast ? Could you help me ?
    I have one idea using SSE2: if esi is 16 bit aligned and edi= esi+16
    we may use movdqa  xmm0, [esi] and movdqa   [edi],xmm0.
    May be also movda  xmm0, [esi], movdqa xmm1, [esi+16]
    and movdqa [edi], xmm0, movdqa  [edi+16], xmm1 if edi=esi+32.
    The first 16 or 32 bytes are 0,
    Thanks  :t
THIS:
CleaningLargeBuffer     proc        pBuffer:DWORD, lBuffer:DWORD
                        push        ecx
                        push        esi
                        ;
                        mov         esi, pBuffer
                        mov         ecx, lBuffer
                        xor          eax, eax                       
                        ;------------------------------------
                        ;      clean the first 16 bytes
                        ;------------------------------------
                        mov         [esi+0],  eax
                        mov         [esi+4],  eax
                        mov         [esi+8],  eax
                        mov         [esi+12], eax               ; 16 bytes
                       
                        ;------------------------------------
                        ;      clean the last 64 bytes
                        ;------------------------------------
                        movdqu      xmm0, [esi]
                        movdqu      [esi+ecx-64], xmm0
                        movdqu      [esi+ecx-48], xmm0
                        movdqu      [esi+ecx-32], xmm0
                        movdqu      [esi+ecx-16], xmm0
                        ;----------------------------------
                        ;       align address
                        ;----------------------------------
                        mov         eax, esi
                        neg         eax
                        and         eax, 15
                        jz          short _aligned0
                        ;---------------------------------------
                        add         esi, eax
                        sub         ecx, eax     
                        ;----------------------------------------
          _aligned0:    and         ecx, -64
                        ;------------------------------------
                        ;      clean the first 64 bytes
                        ;------------------------------------
                        movdqa      [esi+16], xmm0
                        movdqa      [esi+32], xmm0
                        movdqa      [esi+48], xmm0

                 @@:    sub         ecx, 64
                        movdqa      [esi+ecx],    xmm0
                        movdqa      [esi+ecx+16], xmm0
                        movdqa      [esi+ecx+32], xmm0
                        movdqa      [esi+ecx+48], xmm0
                        jnz             short @B

                        pop         esi
                        pop         ecx
                        ret         
CleaningLargeBuffer     endp

hutch--

As 177k is a small amount, "rep stosd" would be easily fast enough.

jj2007

Quote from: hutch-- on December 18, 2016, 02:34:55 PM
"rep stosd" would be easily fast enough.

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  mov ecx, 200000
  Let edi=New$(ecx)
  mov eax, Mirror$("Ciao")
  shr ecx, 2
  NanoTimer()
  rep stosd
  Inkey Str$("That took a whopping %i µs", NanoTimer(µs))
EndOfCode


Output:
That took a whopping 10 µs

RuiLoureiro

#3
Thanks Hutch and Jochen
Jochen could you test my procedure, please ?

jj2007

Sure, here it is:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
rep stosd  took  15 µs
Rui's proc took  82 µs\

rep stosd  took  28 µs
Rui's proc took  92 µs\

rep stosd  took  26 µs
Rui's proc took  84 µs\

rep stosd  took  31 µs
Rui's proc took  92 µs\

rep stosd  took  31 µs
Rui's proc took  220 µs\

rep stosd  took  25 µs
Rui's proc took  100 µs\

rep stosd  took  28 µs
Rui's proc took  96 µs\

rep stosd  took  31 µs
Rui's proc took  70 µs\

rep stosd  took  31 µs
Rui's proc took  95 µs\

rep stosd  took  31 µs
Rui's proc took  93 µs\


Project attached.

RuiLoureiro

Very well Jochen, thank you so much  ;)
I will do another to move - each step- 128 bytes

RuiLoureiro

Jochen, take this one, please.
It moves 128 bytes in each loop, now.
Please use it with a buffer of 117 000 bytes or so.

CleaningLargeBuffer     proc        pBuffer:DWORD, lBuffer:DWORD
                        push        ecx
                        push        esi
                        ;
                        mov         esi, pBuffer
                        mov         ecx, lBuffer
                        xor          eax, eax                       
                        ;------------------------------------
                        ;      clean the first 16 bytes
                        ;------------------------------------
                        mov         [esi+0],  eax
                        mov         [esi+4],  eax
                        mov         [esi+8],  eax
                        mov         [esi+12], eax               ; 16 bytes
                        ;------------------------------------
                        ;      clean the last 128 bytes
                        ;------------------------------------
                        movdqu      xmm0, [esi]
                        movdqu      [esi+ecx-128], xmm0
                        movdqu      [esi+ecx-112], xmm0
                        movdqu      [esi+ecx-96], xmm0
                        movdqu      [esi+ecx-80], xmm0

                        movdqu      [esi+ecx-64], xmm0
                        movdqu      [esi+ecx-48], xmm0
                        movdqu      [esi+ecx-32], xmm0
                        movdqu      [esi+ecx-16], xmm0
                        ;----------------------------------
                        ;       align address
                        ;----------------------------------
                        mov         eax, esi
                        neg         eax
                        and         eax, 15
                        jz          short _aligned0
                        ;---------------------------------------
                        add         esi, eax
                        sub         ecx, eax     
                        ;----------------------------------------
          _aligned0:    and         ecx, -128       ;64
                        ;------------------------------------
                        ;      clean the first 128 bytes
                        ;------------------------------------
                        movdqa      [esi+16], xmm0
                        movdqa      [esi+32], xmm0
                        movdqa      [esi+48], xmm0
                       
                        movdqa      [esi+64], xmm0
                        movdqa      [esi+80], xmm0
                        movdqa      [esi+96], xmm0
                        movdqa      [esi+112], xmm0

                 @@:    sub         ecx, 128        ; 64
                        movdqa      [esi+ecx],    xmm0
                        movdqa      [esi+ecx+16], xmm0
                        movdqa      [esi+ecx+32], xmm0
                        movdqa      [esi+ecx+48], xmm0

                        movdqa      [esi+ecx+64], xmm0
                        movdqa      [esi+ecx+80], xmm0
                        movdqa      [esi+ecx+96], xmm0
                        movdqa      [esi+ecx+112], xmm0
                        jnz             short @B

                        pop         esi
                        pop         ecx
                        ret         
CleaningLargeBuffer     endp

jj2007


RuiLoureiro

Quote from: jj2007 on December 19, 2016, 11:13:43 AM
test yourself...
Thanks but i can't see any results because it doesnt stop, it closes yhe window and exit Jochen !

jj2007

Start it from a DOS prompt...

RuiLoureiro

The last is nearly better. Would you mind to use this:


$StackpBuffer           = 8
$StacklBuffer           = 12
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ALIGN 16
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
CleaningLargeBuffer     proc        pBuffer:DWORD, lBuffer:DWORD
                        push        esi
                        ;
                        mov         esi, [esp+$StackpBuffer]
                        mov         ecx, [esp+$StacklBuffer]
                        xor         eax, eax                       
                        ;------------------------------------
                        ;      clean the first 16 bytes
                        ;------------------------------------
                        mov         [esi+0],  eax
                        mov         [esi+4],  eax
                        mov         [esi+8],  eax
                        mov         [esi+12], eax               ; 16 bytes                       
                        ;------------------------------------
                        ;      clean the last 256 bytes
                        ;------------------------------------
                        movdqu      xmm0, [esi]

                        movdqu      [esi+ecx-256],xmm0
                        movdqu      [esi+ecx-240],xmm0
                        movdqu      [esi+ecx-224],xmm0
                        movdqu      [esi+ecx-208],xmm0
                        movdqu      [esi+ecx-192],xmm0
                        movdqu      [esi+ecx-176],xmm0
                        movdqu      [esi+ecx-160],xmm0
                        movdqu      [esi+ecx-144],xmm0
                        movdqu      [esi+ecx-128],xmm0
                        movdqu      [esi+ecx-112],xmm0
                        movdqu      [esi+ecx-96], xmm0
                        movdqu      [esi+ecx-80], xmm0

                        movdqu      [esi+ecx-64], xmm0
                        movdqu      [esi+ecx-48], xmm0
                        movdqu      [esi+ecx-32], xmm0
                        movdqu      [esi+ecx-16], xmm0
                        ;----------------------------------
                        ;       align address
                        ;----------------------------------
                        mov         eax, esi
                        neg         eax
                        and         eax, 15
                        jz          short _aligned0
                        ;---------------------------------------
                        add         esi, eax
                        sub         ecx, eax
                        ;----------------------------------------
          _aligned0:    and         ecx, -256
                        ;------------------------------------
                        ;      clean the first 256 bytes
                        ;------------------------------------
                        movdqa      [esi+16], xmm0
                        movdqa      [esi+32], xmm0
                        movdqa      [esi+48], xmm0                       
                        movdqa      [esi+64], xmm0
                        movdqa      [esi+80], xmm0
                        movdqa      [esi+96], xmm0
                        movdqa      [esi+112],xmm0
                        movdqa      [esi+128],xmm0
                        movdqa      [esi+144],xmm0
                        movdqa      [esi+160],xmm0
                        movdqa      [esi+176],xmm0
                        movdqa      [esi+192],xmm0
                        movdqa      [esi+208],xmm0
                        movdqa      [esi+224],xmm0
                        movdqa      [esi+240],xmm0

             _loop0:    sub         ecx, 256

                        movdqa      [esi+ecx],    xmm0
                        movdqa      [esi+ecx+16], xmm0
                        movdqa      [esi+ecx+32], xmm0
                        movdqa      [esi+ecx+48], xmm0
                        movdqa      [esi+ecx+64], xmm0
                        movdqa      [esi+ecx+80], xmm0
                        movdqa      [esi+ecx+96], xmm0
                        movdqa      [esi+ecx+112],xmm0
                        movdqa      [esi+ecx+128],xmm0
                        movdqa      [esi+ecx+144],xmm0
                        movdqa      [esi+ecx+160],xmm0
                        movdqa      [esi+ecx+176],xmm0
                        movdqa      [esi+ecx+192],xmm0
                        movdqa      [esi+ecx+208],xmm0
                        movdqa      [esi+ecx+224],xmm0
                        movdqa      [esi+ecx+240],xmm0
                        jnz         _loop0

              _exit:    pop         esi
                        ret         8
CleaningLargeBuffer     endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


jj2007

Much better :tIntel(R) Core(TM) i5-2450M CPU @ 2.50GHz
rep stosd  took  12 µs
Rui's proc took  25 µs

rep stosd  took  18 µs
Rui's proc took  25 µs

rep stosd  took  14 µs
Rui's proc took  33 µs

rep stosd  took  15 µs
Rui's proc took  20 µs

rep stosd  took  7 µs
Rui's proc took  10 µs

rep stosd  took  18 µs
Rui's proc took  25 µs

rep stosd  took  18 µs
Rui's proc took  17 µs

rep stosd  took  18 µs
Rui's proc took  25 µs

rep stosd  took  17 µs
Rui's proc took  34 µs

rep stosd  took  29 µs
Rui's proc took  21 µs

-- hit any key --

RuiLoureiro

 :biggrin: :biggrin:
Too much better  ;)
Thank you Jochen
Quote
Intel(R) Pentium(R) 4 CPU 3.40GHz
rep stosd  took  33 µs
Rui's proc took  35 µs

rep stosd  took  42 µs
Rui's proc took  24 µs

rep stosd  took 44 µs
Rui's proc took  26 µs

rep stosd  took  21 µs
Rui's proc took  24 µs

rep stosd  took 78 µs
Rui's proc took  28 µs
Sorry...
Quote
Intel(R) Pentium(R) 4 CPU 3.40GHz
rep stosd  took  33 µs
Rui's proc took  35 µs

rep stosd  took 42 µs
Rui's proc took  24 µs

rep stosd  took  44 µs
Rui's proc took  26 µs

rep stosd  took  21 µs
Rui's proc took  24 µs

rep stosd  took  78 µs
Rui's proc took  28 µs

rep stosd  took  22 µs
Rui's proc took  22 µs

rep stosd  took 22 µs
Rui's proc took  20 µs

rep stosd  took  21 µs
Rui's proc took  21 µs

rep stosd  took 31 µs
Rui's proc took  23 µs

rep stosd  took  23 µs
Rui's proc took  20 µs

-- hit any key --

RuiLoureiro

#13
 :biggrin: :biggrin: 
Hi Jochen             
Here we have the procedure to clean 114028 bytes in
the proc ResolveExpress. But i aligned the address (see there )
and the total length to clean  is a multiple of 512 bytes
(114 176 bytes- the last space is not used).
Is it possible to test it ? 
Thanks  ;)

$StackpBuffer           = 8
$StacklBuffer           = 12
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ALIGN 16
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
CleanAligned512Buffer   proc        pBuffer:DWORD, lBuffer:DWORD
                        push        esi
                        ;
                        mov         esi, [esp+$StackpBuffer]
                        mov         ecx, [esp+$StacklBuffer]
                        xor         eax, eax
                       
                        ;------------------------------------
                        ;      clean the first 16 bytes
                        ;------------------------------------
                        mov         [esi+0],  eax
                        mov         [esi+4],  eax
                        mov         [esi+8],  eax
                        mov         [esi+12], eax               ; 16 bytes
                       
                        ;------------------------------------
                        ;     load xmm0 with 16 bytes
                        ;------------------------------------
                        movdqu      xmm0, [esi]
                       
                        ;----------------------------------
                        ;       align address
                        ;----------------------------------
                        ;mov         eax, esi
                        ;neg         eax
                        ;and         eax, 15
                        ;jz          short _aligned0
               
                        ;---------------------------------------
                        ;add         esi, eax
                        ;sub         ecx, eax
                       
                        ;----------------------------------------
          _aligned0:    and         ecx, -512


             _loop0:    sub         ecx, 512

                        movdqa      [esi+ecx],    xmm0
                        movdqa      [esi+ecx+16], xmm0
                        movdqa      [esi+ecx+32], xmm0
                        movdqa      [esi+ecx+48], xmm0
                        movdqa      [esi+ecx+64], xmm0
                        movdqa      [esi+ecx+80], xmm0
                        movdqa      [esi+ecx+96], xmm0
                       
                        movdqa      [esi+ecx+112],xmm0
                        movdqa      [esi+ecx+128],xmm0
                        movdqa      [esi+ecx+144],xmm0
                        movdqa      [esi+ecx+160],xmm0
                        movdqa      [esi+ecx+176],xmm0
                        movdqa      [esi+ecx+192],xmm0
                       
                        movdqa      [esi+ecx+208],xmm0
                        movdqa      [esi+ecx+224],xmm0
                        movdqa      [esi+ecx+240],xmm0
                        movdqa      [esi+ecx+256],xmm0
                        movdqa      [esi+ecx+272],xmm0
                        movdqa      [esi+ecx+288],xmm0
                       
                        movdqa      [esi+ecx+304],xmm0
                        movdqa      [esi+ecx+320],xmm0
                        movdqa      [esi+ecx+336],xmm0
                        movdqa      [esi+ecx+352],xmm0
                        movdqa      [esi+ecx+368],xmm0
                        movdqa      [esi+ecx+384],xmm0
                       
                        movdqa      [esi+ecx+400],xmm0
                        movdqa      [esi+ecx+416],xmm0
                        movdqa      [esi+ecx+432],xmm0
                        movdqa      [esi+ecx+448],xmm0
                        movdqa      [esi+ecx+464],xmm0
                        movdqa      [esi+ecx+480],xmm0
                        movdqa      [esi+ecx+496],xmm0                       
                        jnz         _loop0

              _exit:    pop         esi
                        ret         8
CleanAligned512Buffer   endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; rcl0_pRclStr            equ rcl0_lenstackbuffer + 8
; rcl_pRclStr             equ dword ptr [ebp+rcl0_pRclStr]
Quote
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ResolveExpress                  proc        pRclStr:DWORD
                                push        ebp

                                mov         ecx, rcl0_lenstackbuffer        ; = 114 556 -> usefull 114 028
                                sub         esp, ecx
                                mov         ebp, esp
                                ;
                                mov         eax, ebp
                                neg         eax
                                and         eax, 15
                                jz          short @F

                                add         ebp, eax
                                sub         ecx, eax

                        @@:     push        ebx
                                push        esi
                                push        edi
                                ;

                                invoke      CleanAligned512Buffer, ebp, ecx
                                ;mov         esi, rcl_pRclStr
                                ;--------------
                                ; do something
                                ;--------------
                               
                                pop         edi
                                pop         esi
                                pop         ebx


                                add         esp, rcl0_lenstackbuffer
                                clc
                                pop         ebp
                                ret         4
ResolveExpress                  endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


jj2007

Here you are:

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
rep stosd  took  61 µs
Rui's proc took  32 µs

rep stosd  took  18 µs
Rui's proc took  16 µs

rep stosd  took  15 µs
Rui's proc took  49 µs

rep stosd  took  17 µs
Rui's proc took  16 µs

rep stosd  took  18 µs
Rui's proc took  20 µs

rep stosd  took  18 µs
Rui's proc took  20 µs

rep stosd  took  16 µs
Rui's proc took  17 µs

rep stosd  took  41 µs
Rui's proc took  16 µs

rep stosd  took  17 µs
Rui's proc took  37 µs

rep stosd  took  18 µs
Rui's proc took  20 µs