flat assembler
Message board for the users of flat assembler.
Index
> Windows > stack and recursion |
Author |
|
beppe85 31 Dec 2004, 22:20
If you figure out how to do this, you could have the fastest decent recursive compilers. OK, I guess I've figured out, but let's talk about the problem.
To return fast from a deeply recursive function, you at first need to unwind the stack, which is usually done by just ret-urning from the current procedure. So this would not be a 'fast return'. Implementation direction(slowest-to-fastest): - call/return(usual way) - loop retriving calling-ebp and moving to esp, until the destination is reached. - mantain a display-like structure in each routine, ie. an array with entries representing the caller's stack frame, plus return adresses. Recursive functions are to be special case'd. Now that you know the ways to go, I hope you understand that the first give the best cost-benefit, and less error-prone, approach. I've never implemented the last nor proved it correct, so I could not continue describing it. Hope someday I do this. I propose you to do the following, on return: the callee, set CF(=0:not found; =1: found); the caller, check CF and ret if needed. Code: ... stdcall _findfile,edi,[lpFileToFind],[lpBuffer] jc .ret_found .found_file: ... jmp .ret_found ... .close_find: invoke FindClose,[.hFind] jmp .ret_not_found ... .ret_found: stc return .ret_not_found: clc return Hope this help, and thank you for the insight. Happy new year for you too! |
|||
31 Dec 2004, 22:20 |
|
Vasilev Vjacheslav 01 Jan 2005, 13:09
ok, i align the stack and works fine. I've tryed my method before, but there were mistakes with arithmethics
but i found other problem after open FindFirstFile i must close handle (is that true?), when file is found there still open handles (iFiles contains number of open handles also number of un-returned recursion call) Code: format pe gui 4.0 entry start include '%fasminc%\win32a.inc' MAX_PATH = 260 section '.idata' data readable writeable szPath db "c:\chat",0 szFile db "basic.mrc",0 szMask db "*.*",0 section '.udata' readable writeable szBuffer rb MAX_PATH iFiles dd ? section '.code' code readable executable start: xor eax,eax mov [iFiles],eax stdcall _findfile,szPath,szFile,szBuffer invoke ExitProcess,NULL proc _findfile, lpStartPath,lpFileToFind,lpBuffer .wfd FINDDATA .szPath rb MAX_PATH .szSubPath rb MAX_PATH .hFind dd ? enter lea edi,[.szPath] invoke lstrcpy,edi,[lpStartPath] invoke lstrlen,edi cmp byte [edi+eax-1],"\" je @F cmp byte [edi+eax-1],"/" je @F xor esi,esi add esi,05Ch mov word [edi+eax],si @@: invoke lstrcat,edi,szMask lea esi,[.wfd] stdcall _zeromem,esi,sizeof.FINDDATA invoke FindFirstFile,edi,esi or eax,eax jl .error_find mov [.hFind],eax .while_start: lea esi,[.wfd.cFileName] lodsw sub esi,2 cmp ax,"." je .next_file cmp ax,".." je .next_file lea edi,[.wfd] mov eax,[edi+FINDDATA.dwFileAttributes] test ax,FILE_ATTRIBUTE_DIRECTORY je .else lea edi,[.szSubPath] push edi stdcall _zeromem,edi,MAX_PATH mov edi,[esp] lea eax,[.szPath] invoke lstrcpy,edi,eax invoke lstrlen,edi mov byte [edi+eax-3],0 invoke lstrcat,edi,esi pop edi inc [iFiles] pushad stdcall _findfile,edi,[lpFileToFind],[lpBuffer] popad dec [iFiles] jmp .next_file .found_file: lea esi,[.szPath] mov edi,[lpBuffer] invoke lstrlen,esi mov byte [esi+eax-3],NULL invoke lstrcpy,edi,esi lea esi,[.wfd.cFileName] invoke lstrcat,edi,esi mov ecx,896 ; 844+32+20 (stack data, pushad size, params) mov eax,[iFiles] imul eax,ecx add ebp,eax mov esp,ebp jmp .close_find .else: invoke lstrcmpi,[lpFileToFind],esi or eax,eax jz .found_file .next_file: lea edi,[.wfd] invoke FindNextFile,[.hFind],edi or eax,eax jg .while_start .close_find: invoke FindClose,[.hFind] .error_find: return endp proc _zeromem, var,size invoke RtlZeroMemory,[var],[size] return endp section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ user32,'user32.dll',\ shell32,'shell32.dll',\ advapi32,'advapi32.dll' include '%fasminc%\apia\kernel32.inc' include '%fasminc%\apia\user32.inc' include '%fasminc%\apia\shell32.inc' include '%fasminc%\apia\advapi32.inc' ; eof _________________ [not enough memory] |
|||
01 Jan 2005, 13:09 |
|
beppe85 01 Jan 2005, 13:19
Yes, this is the real problem which precudes from a fast-return: you need to call the finalization code always.
In this case, jump into .close_find(you can invoke FindClose inline too) before return. |
|||
01 Jan 2005, 13:19 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.