В общем, есть процедура, которая по заданной базовой директории роется в поисках .txt. Проблема в том, что адреса возврата иногда затираются, или же в конце концов esp указывает не на правильный адрес. Просидел пол дня с отладчиком, но так ничего наводящего на мысль не накопал. Кодесс: Код (Text): format PE include 'D:\asm\fasmw16925\INCLUDE\win32a.inc' section '.code' readable writable executable entry start start: mov eax,dword direct call find_txt invoke ExitProcess,0 ;in -> EAX - адрес строки с директорией proc find_txt local path db 260 dup (?);MAX_PATH local hFile dd ? local find WIN32_FIND_DATA push edi push esi push eax lea edi,[path] mov esi,eax .copy_strings: cmp byte[esi],0 je .continue mov eax,[esi] mov [edi],eax inc edi inc esi jmp .copy_strings .continue: pop eax pop esi pop edi ;lea eax,[path] ;invoke MessageBox,0,eax,mark1,0 pushad lea edi,[path] push edi call lstrlen dec eax mov byte [edi+eax+1],'/' mov byte [edi+eax+2],'*' mov byte [edi+eax+3],0 lea ebx,[find] lea edi,[path] invoke FindFirstFile,edi,ebx cmp eax,0xFFFFFFFF je .fail mov [hFile],eax .cycle: push edi push esi mov edi,[hFile] lea edi,[edi] lea esi,[find] invoke FindNextFile,edi,esi pop esi pop edi test eax,eax jz .fail ;lea eax,[path] ;invoke MessageBox,0,eax,mark2,0 lea eax,[find] add eax,44 cmp word[eax],'..' je .cycle lea eax,[find] mov eax,[eax] and eax,FILE_ATTRIBUTE_DIRECTORY lea ebx,[find] mov ebx,[ebx] cmp ebx,FILE_ATTRIBUTE_DIRECTORY jne .got_file lea ecx,dword[find] add ecx,44; 44 - смещении имени cmp byte[ecx],'.' je .got_file ;если откопали директорию lea edi,[path] push edi call lstrlen add edi,eax lea esi,dword [find] add esi,44 push esi call lstrlen mov ecx,eax dec edi rep movsb;сливаем в путь для передачи mov byte[edi],'/' mov byte[edi+1],0 ;push eax ;lea eax,[path] ;invoke MessageBox,0,eax,mark3,0 ;pop eax lea eax,[path] call find_txt;ок, теперь смотрим во вложенной директории ;и вот при возврате из вложенной функции вылетаем не туда... ;т.к ESP при call'е указывал на другое значение, чем после ;Если быть точнее, то на прыгаем на 0 ;приводим путь в нормальный вид lea eax,dword[find] add eax,44 push eax call lstrlen sub edi,eax mov byte[edi],0 jmp .cycle .got_file: lea eax,[find] add eax,44 ;lea ebx,[path] ;push eax ;invoke MessageBox,0,eax,ebx,0 ;pop eax mov ecx,56 .check_name: cmp dword [eax],'.txt' je .found cmp dword [eax],'.TXT' je .found test ecx,ecx jz .cycle inc eax dec ecx jmp .check_name .found: invoke MessageBox,0,got_txt,got_txt,0 jmp .cycle .fail: popad ret endp lstrlen: add esp,4 pop eax sub esp,8 push ecx xor ecx,ecx .cycle: cmp byte[eax],0 je .found inc eax inc ecx jmp .cycle .found: mov eax,ecx pop ecx ret ;Тут всякие импортируемые функции, переменные глобальные... end data Стековый фрейм формируется, в конце, перед ret'ом, как и положено, стоит leave, лишних push'ев я здесь не нашёл (бывает у меня так - забываю из стека забрать что-нибудь). Вот, собственно и всё.
Ну здравствуй, Тришин Гена Ищет на C:\ Что-то на васм не льёт. Сейчас на помойку скину. http://ifolder.ru/25677379 ЗЫ. Зачем вам бинарь? Уже бы фасм давно стянули и скомпилили.
Код (Text): format PE include 'D:\asm\fasmw16925\INCLUDE\win32a.inc' section '.code' readable writable executable entry start start: mov eax,dword direct call find_txt invoke ExitProcess,0 ;in -> EAX - адрес строки с директорией proc find_txt local path db 260 dup (?);MAX_PATH local hFile dd ? local find WIN32_FIND_DATA push edi push esi push eax lea edi,[path] mov esi,eax .copy_strings: cmp byte[esi],0 je .continue mov eax,[esi] mov [edi],eax inc edi inc esi jmp .copy_strings .continue: pop eax pop esi pop edi ;lea eax,[path] ;invoke MessageBox,0,eax,mark1,0 pushad lea edi,[path] push edi call lstrlen dec eax mov byte [edi+eax+1],'/' mov byte [edi+eax+2],'*' mov byte [edi+eax+3],0 lea ebx,[find] lea edi,[path] invoke FindFirstFile,edi,ebx cmp eax,0xFFFFFFFF je .fail mov [hFile],eax .cycle: push edi push esi mov edi,[hFile] lea edi,[edi] lea esi,[find] invoke FindNextFile,edi,esi pop esi pop edi test eax,eax jz .fail ;lea eax,[path] ;invoke MessageBox,0,eax,mark2,0 lea eax,[find] add eax,44 cmp word[eax],'..' je .cycle lea eax,[find] mov eax,[eax] and eax,FILE_ATTRIBUTE_DIRECTORY lea ebx,[find] mov ebx,[ebx] cmp ebx,FILE_ATTRIBUTE_DIRECTORY jne .got_file lea ecx,dword[find] add ecx,44; 44 - смещении имени cmp byte[ecx],'.' je .got_file ;если откопали директорию lea edi,[path] push edi call lstrlen add edi,eax lea esi,dword [find] add esi,44 push esi call lstrlen mov ecx,eax dec edi rep movsb;сливаем в путь для передачи mov byte[edi],'/' mov byte[edi+1],0 ;push eax ;lea eax,[path] ;invoke MessageBox,0,eax,mark3,0 ;pop eax lea eax,[path] call find_txt;ок, теперь смотрим во вложенной директории ;и вот при возврате из вложенной функции вылетаем не туда... ;т.к ESP при call'е указывал на другое значение, чем после ;Если быть точнее, то на прыгаем на 0 ;приводим путь в нормальный вид lea eax,dword[find] add eax,44 push eax call lstrlen sub edi,eax mov byte[edi],0 jmp .cycle .got_file: lea eax,[find] add eax,44 ;lea ebx,[path] ;push eax ;invoke MessageBox,0,eax,ebx,0 ;pop eax mov ecx,56 .check_name: cmp dword [eax],'.txt' je .found cmp dword [eax],'.TXT' je .found test ecx,ecx jz .cycle inc eax dec ecx jmp .check_name .found: invoke MessageBox,0,got_txt,got_txt,0 jmp .cycle .fail: popad ret endp lstrlen: add esp,4 pop eax sub esp,8 push ecx xor ecx,ecx .cycle: cmp byte[eax],0 je .found inc eax inc ecx jmp .cycle .found: mov eax,ecx pop ecx ret section '.data' readable writable direct db 'C:/',0 got_txt db 'Got it',0 mark1 db 'mark1',0; для отладки mark2 db 'mark2',0 mark3 db 'mark3',0 section '.import' readable writable data import library kernel32,'KERNEL32.DLL'\ user32,'USER32.DLL' import kernel32,\ ExitProcess,'ExitProcess',\ FindFirstFile,'FindFirstFileA',\ FindNextFile,'FindNextFileA' import user32,\ MessageBox,'MessageBoxA' end data
Должно быть копирование по одному байту, а не по четыре. Слеши, кстати ставить обратные: не / а \. Не поможет в случае ".TxT". Для таких случаев есть lstrcmpi. Вот рабочий код: Код (Text): format PE CONSOLE 5.0 include "win32wxp.inc" entry start section ".text" code readable executable dir_name TCHAR "C:\", 0 asterisk TCHAR "*", 0 txt_extension TCHAR ".txt", 0 line_feed TCHAR 10 start: stdcall find_txt, dir_name invoke Sleep, -1 invoke ExitProcess, 0 proc find_txt uses ebx esi edi, dir_name local wfd:WIN32_FIND_DATA local search_mask[MAX_PATH]:TCHAR local file_name[MAX_PATH]:TCHAR lea esi, [search_mask] lea edi, [file_name] invoke lstrcpy, esi, [dir_name] invoke PathCombine, esi, esi, asterisk invoke FindFirstFile, esi, addr wfd cmp eax, INVALID_HANDLE_VALUE je .end_search mov ebx, eax .do_search: invoke PathCombine, edi, [dir_name], addr wfd.cFileName test [wfd.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY jnz .dir_found .file_found: invoke PathFindExtension, edi invoke lstrcmpi, eax, txt_extension test eax, eax jnz .continue_search .txt_file_found: invoke WriteConsole, <invoke GetStdHandle, STD_OUTPUT_HANDLE>, edi, <invoke lstrlen, edi>, NULL, NULL invoke WriteConsole, <invoke GetStdHandle, STD_OUTPUT_HANDLE>, line_feed, 1, NULL, NULL jmp .continue_search .dir_found: cmp [wfd.cFileName], '.' ; skip . and .. je .continue_search stdcall find_txt, edi .continue_search: invoke FindNextFile, ebx, addr wfd test eax, eax jnz .do_search .end_search: ret endp section ".idata" import data readable writeable library kernel32, "kernel32.dll", \ shlwapi, "shlwapi.dll" include "api\kernel32.inc" import shlwapi, \ PathCombineA, "PathCombineA", \ PathCombineW, "PathCombineW", \ PathFindExtensionA, "PathFindExtensionA", \ PathFindExtensionW, "PathFindExtensionW" api PathCombine, \ PathFindExtension
Код (Text): lstrlen: add esp,4 pop eax sub esp,8 push ecx xor ecx,ecx .cycle: cmp byte[eax],0 je .found inc eax inc ecx jmp .cycle .found: mov eax,ecx pop ecx ret А кто будет восстанавливать стек? Виновата именно эта функция
Ezrah, слеши не менял, всё равно работает. Ищет то хорошо, проблема в стеке. Да, с копированием я тупанул. Исправил. (Хотя, в принципе, результат одинаков). h0t, что то не допёр. Если вы про стековый фрейм, то в начале Код (Text): push ebp ; mov ebp,esp ; enter sub esp,554 ; а в конце Код (Text): popad mov esp,ebp ;leave pop ebp ; ret Так что про какое восстановление стека Вы говорите? Стек после локальных переменных восстанавливаем, вроде бы лишних push'ев нет.
h0t,Ezrah, да, была у меня такая мысль... Но что-то на неё я не особо посмотрел. А слона то я и не заметил Спасибо. Вот отредактированный на свежую голову вариант (может кому-нибудь понадобится): Код (Text): format PE include 'D:\asm\fasmw16925\INCLUDE\win32a.inc' section '.code' readable writable executable entry start start: mov eax,dword direct call find_txt invoke ExitProcess,0 ;__fastcall find_txt(DWORD Dir) proc find_txt local path dd 260 dup (?);MAX_PATH local hFile dd ? local find WIN32_FIND_DATA push edi push esi push eax lea edi,[path] mov esi,eax .copy_strings: cmp byte[esi],0 je .continue mov al,byte[esi] mov [edi],al inc edi inc esi jmp .copy_strings .continue: mov byte[edi],0 lea edi,[path] invoke MessageBox,0,edi,edi,0 pop eax pop esi pop edi pushad lea edi,[path] push edi call lstrlen dec eax mov byte [edi+eax+1],'/' mov byte [edi+eax+2],'*' mov byte [edi+eax+3],0 lea ebx,[find] lea edi,[path] invoke FindFirstFile,edi,ebx cmp eax,0xFFFFFFFF je .fail mov [hFile],eax .cycle: push edi push esi mov edi,[hFile] lea edi,[edi] lea esi,[find] invoke FindNextFile,edi,esi pop esi pop edi test eax,eax jz .fail lea eax,[find] add eax,44 cmp word[eax],'..' je .cycle lea eax,[find] mov eax,[eax] and eax,FILE_ATTRIBUTE_DIRECTORY cmp eax,FILE_ATTRIBUTE_DIRECTORY jne .got_file lea ecx,dword[find] add ecx,44 cmp byte[ecx],'.' je .got_file lea edi,[path] push edi call lstrlen add edi,eax lea esi,dword [find] add esi,44 push esi call lstrlen mov ecx,eax dec edi rep movsb mov byte[edi],'/' mov byte[edi+1],0 lea eax,[path] call find_txt lea eax,dword[find] add eax,44 push eax call lstrlen sub edi,eax mov byte[edi],0 jmp .cycle .got_file: lea eax,[find] add eax,44 lea ebx,[path] lea ecx,[find] add ecx,44 push eax push ecx call lstrlen mov ecx,eax pop eax .check_name: cmp dword [eax],'.txt' je .found cmp dword [eax],'.TXT' je .found test ecx,ecx jz .cycle inc eax dec ecx jmp .check_name .found: invoke MessageBox,0,got_txt,got_txt,0 lea edi,[path] lea esi,[find] add esi,44 invoke MessageBox,0,edi,esi,0 jmp .cycle .fail: popad ret endp lstrlen: add esp,4 pop eax sub esp,8 push ecx xor ecx,ecx .cycle: cmp byte[eax],0 je .found inc eax inc ecx jmp .cycle .found: mov eax,ecx pop ecx retn 4 section '.data' readable writable direct db 'D:/',0 db 100 dup (0) got_txt db 'We got it',0 section '.import' readable writable data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' import kernel32,\ ExitProcess,'ExitProcess',\ FindFirstFile,'FindFirstFileA',\ FindNextFile,'FindNextFileA',\ HeapAlloc,'HeapAlloc' import user32,\ MessageBox,'MessageBoxA' end data