flat assembler
Message board for the users of flat assembler.
Index
> Windows > How extend local space in 'proc' |
Author |
|
Tomasz Grysztar 02 Oct 2011, 11:13
Use the "sp_prologue" example from the documentation. It does a stack probing for areas larger than 1000h bytes.
|
|||
02 Oct 2011, 11:13 |
|
marcinzabrze12 02 Oct 2011, 15:36
my english don't let me to know it, can you show some example it will a lot simply for me. Sorry for my English I'm beginner
|
|||
02 Oct 2011, 15:36 |
|
bitRAKE 02 Oct 2011, 17:22
Simple example of dynamic stack size:
http://board.flatassembler.net/topic.php?p=31713#31713 |
|||
02 Oct 2011, 17:22 |
|
Tomasz Grysztar 02 Oct 2011, 18:59
marcinzabrze12 wrote: my english don't let me to know it, can you show some example it will a lot simply for me. Sorry for my English I'm beginner Code: include 'win32a.inc' ; or other version macro sp_prologue procname,flag,parmbytes,localbytes,reglist { local loc loc = (localbytes+3) and (not 3) parmbase@proc equ ebp+8 localbase@proc equ ebp-loc if parmbytes | localbytes push ebp mov ebp,esp if localbytes repeat localbytes shr 12 mov byte [esp-%*4096],0 end repeat sub esp,loc end if end if irps reg, reglist \{ push reg \} } prologue@proc equ sp_prologue ; here your program code |
|||
02 Oct 2011, 18:59 |
|
marcinzabrze12 02 Oct 2011, 19:51
Tomasz like this ?
dll code: Code: format PE GUI 4.0 DLL entry DllEntryPoint PATH_LIMIT equ 32767 include 'win32ax.inc' section '.data' data readable writeable shareable ; Dane dla procedury ScanFolder: PathBuffer db PATH_LIMIT dup ? hSearchA dd ? ; wskazniki referencyjne: cFileName dd ? section '.text' code readable executable proc DllEntryPoint hinstDLL, fdwReason, lpvReserved mov eax,TRUE ret endp macro sp_prologue procname,flag,parmbytes,localbytes,reglist { local loc loc = (localbytes+3) and (not 3) parmbase@proc equ ebp+8 localbase@proc equ ebp-loc if parmbytes | localbytes push ebp mov ebp,esp if localbytes repeat localbytes shr 12 mov byte [esp-%*4096],0 end repeat sub esp,loc end if end if irps reg, reglist \{ push reg \} } prologue@proc equ sp_prologue ; VOID ScanTree (LPSTR startdirectory, LPSTR name_filter, LPWIN32_FIND_DATA winfind, PROC_ADDRESS proced); proc ScanTree startdirectory, name_filter, winfind, proced locals handle dd ? path db 3000 dup ? endl macro Service { lea ebx, [path] mov eax, [winfind] add eax, WIN32_FIND_DATA.cFileName cinvoke wsprintf, ebx, '%hs\%hs', [startdirectory], eax stdcall ScanTree, ebx, [name_filter], [winfind], [proced] } stdcall ScanFolder, [startdirectory], [name_filter], [winfind], [proced] lea ebx, [path] cinvoke wsprintf, ebx, '%hs\*', [startdirectory] invoke FindFirstFile, ebx, [winfind] cmp eax, INVALID_HANDLE_VALUE je .the_end mov [handle], eax stdcall IsSubdir, [winfind] test eax, eax jnz .find_next Service .find_next: invoke FindNextFile, [handle], [winfind] test eax, eax jz @f stdcall IsSubdir, [winfind] test eax, eax jnz .find_next Service jmp .find_next @@: invoke FindClose, [handle] .the_end: ret endp ; .................................................................................................. ; INT ScanFolder (LPSTR folder, LPSTR name_filter, LPWIN32_FIND_DATA winfind, PROC_ADDRESS proced); ; ; opis: Przeszukuje podany katalog w poszukiwaniu plikow o pasujacych nazwach. Jezeli trafi na ; pasujaca nazwe wykonuje dla niej procedure ktorej adres jest podany w czwartym parametrze. ; Jezeli podana procedura zwraca zero - funkcja wyszukuje dalej, Jezeli procedura ta zwroci ; wartosc <> zero wtedy ScanFolder natychmiast konczy swoje dzialanie. ; ; return: ; 00 = przeszukano caly katalog ; <> 00 = zatrzymano przez funkcje [proced] ; ; .................................................................................................. proc ScanFolder folder, name_filter, winfind, proced macro FileService { invoke lstrcmp, [cFileName], '.' test eax, eax jz .find_next invoke lstrcmp, [cFileName], '..' test eax, eax jz .find_next cinvoke wsprintf, PathBuffer, '%hs\%hs', [folder], [cFileName] stdcall [proced] test eax, eax jnz .end_stop } .ustawianie_wskaznikow: mov ebx, [winfind] add ebx, WIN32_FIND_DATA.cFileName mov [cFileName], ebx .start: cinvoke wsprintf, PathBuffer, '%hs\%hs', [folder], [name_filter] invoke FindFirstFile, PathBuffer, [winfind] cmp eax, INVALID_HANDLE_VALUE je .end_first mov [hSearchA], eax FileService .find_next: invoke FindNextFile, [hSearchA], [winfind] test eax, eax jz .end_next FileService jmp .find_next .end_stop: inc eax ret .end_next: invoke FindClose, [hSearchA] .end_first: ret endp ; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ; FUNKCJA: IsSubdir WFD ; ; OPIS: ; Sprawdz czy element znajdujacy sie we wskazanej ; strukturze WIN32_FIND_DATA jest katalogiem. ; Jezeli tak to czy jego nazwe nale|y pominac ; podczas przeszukiwania. - nazwy '.' oraz '..' ; ; ARGUMENTY: ; WFD - Pointer na strukture WIN32_FIND_DATA ; ; RETURN: ; 00 - katalog ; 01 - niekatalog (lub nazwa pomijana) ; ; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& proc IsSubdir uses ebx esi edi ebp, WFD:DWORD pushfd locals name1 db '.',0 name2 db '..',0 endl macro IgnoreName name { lea eax, name invoke lstrcmp, ebx, eax test eax, eax jz .end_nie_katalog } ; sprawdzanie czy element w [WFD] jest katalogiem: mov ebx, [WFD] bt dword [ebx], 4 jnc .end_nie_katalog ; sprawdzanie czy ignorowac nazwe elementu w [WFD] mov ebx, [WFD] add ebx, 44 ; pointer nazwy elementu do EBX IgnoreName [name1] IgnoreName [name2] .end_katalog: xor eax, eax popfd ret .end_nie_katalog: mov eax, 01 popfd ret endp; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' section '.edata' export data readable export 'FindFile.dll',\ ScanFolder, 'ScanFolder',\ PathBuffer, 'PathBuffer',\ ScanTree, 'ScanTree' section '.reloc' fixups data discardable and here is program which use this library: Code: format pe gui 4.0 entry start include 'win32ax.inc' PATH_LIMIT equ 32767 prefix fix '\\?\' folder fix 'd:' section '.data' data readable writeable shareable startpath db prefix, folder, 0 name db '*',0 wfd WIN32_FIND_DATA counter dd 0 buf db 100 dup ? pathbuf db PATH_LIMIT dup ? database db '\list of files.rtf',0 Hdatabase dd ? odczyt dd ? newline db 13, 00 komunikat db 'lista plikow w lokalizacji <', folder,'> ',0 section '.code' code readable executable start: invoke SHGetSpecialFolderPath, NULL, pathbuf, CSIDL_DESKTOP, NULL invoke lstrcat, pathbuf, database invoke CreateFile, pathbuf, GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,\ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL .if eax = INVALID_HANDLE_VALUE invoke MessageBox, 0, 'nie udalo sie utworzyc pliku <lista plikow.txt>', 'PODSUMOWANIE', 0 invoke ExitProcess, 0 .endif mov [Hdatabase], eax invoke ScanTree, startpath, name, wfd, service invoke CloseHandle, [Hdatabase] cinvoke wsprintf, buf, '%d', [counter] invoke MessageBox, 0, komunikat, buf, 0 invoke ExitProcess,0 proc service inc [counter] invoke lstrlen, [PathBuffer] cmp eax, MAX_PATH jnae @f mov ebx, eax push [PathBuffer] pop esi add esi, 4 invoke lstrcat, [PathBuffer], newline invoke WriteFile, [Hdatabase], esi, ebx, odczyt, NULL @@: xor eax, eax ret endp section '.idata' import data readable library kernel32,'kernel32.dll',user32,'user32.dll',shell32,'shell32.dll',FindFile,'FindFile.dll',gorf,'gorf32.dll' include 'api\kernel32.inc' include 'api\user32.inc' include 'api\shell32.inc' import FindFile,\ ScanFolder, 'ScanFolder',\ PathBuffer, 'PathBuffer',\ ScanTree, 'ScanTree' when i expand in proc ScanTree local buffer 'path' to 30000 bytes everything will crash. I admit that i understand nothing of sp_prolgue macro but i can't see it in work at least ... ps. at now i'm use LocalAlloc and LocalFree to corectly work this procedure with path longer than MAX_PATH value but i think that use stack space will speed up procedure Last edited by marcinzabrze12 on 02 Oct 2011, 20:34; edited 1 time in total |
|||
02 Oct 2011, 19:51 |
|
Tomasz Grysztar 02 Oct 2011, 20:21
It crashes because you've got another problem - you do deep recursion of procedure that has such a big locals storage, and you eat up stack memory in insane amounts. The crash you get is because of the stack overflow, as you quickly run out of any stack space that Windows is able to provide.
I suggest to create a separate procedure that uses this big local buffer and which is not called recursively - then if you call it from the recursive procedure, it will only allocate this buffer one at a time. |
|||
02 Oct 2011, 20:21 |
|
marcinzabrze12 02 Oct 2011, 20:46
Yes it confirsm my assumptions. I try change method to less recursive. Any way thanks for help.
|
|||
02 Oct 2011, 20:46 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.