поиск в асме

Discussion in 'WASM.BEGINNERS' started by giskar, Aug 4, 2007.

  1. giskar

    giskar New Member

    Blog Posts:
    0
    Joined:
    Aug 2, 2007
    Messages:
    43
    Подскажите пожалста, как в ассемблере осуществить поиск файла, не только в текущем каталоге, но и к примеру по всему диску C:\ или D:\ . Зарание спасибо
     
  2. RamMerLabs

    RamMerLabs Well-Known Member

    Blog Posts:
    0
    Joined:
    Sep 11, 2006
    Messages:
    1,426
    FindFirstFile;FindNextFile работают на УРА!
     
  3. KeSqueer

    KeSqueer Сергей

    Blog Posts:
    0
    Joined:
    Jul 19, 2007
    Messages:
    1,183
    Location:
    Москва
    Недавно тема была 'поиск и удаление файлов'. Поиск рулит!
     
  4. dead_body

    dead_body wasm.ru

    Blog Posts:
    0
    Joined:
    Sep 3, 2004
    Messages:
    603
    Location:
    Украина;г.Харьков;г.Н.Каховка
    так же как и в С,С++,Паскале и дельфи. АПИ функциями.
     
  5. nitrotoluol

    nitrotoluol New Member

    Blog Posts:
    0
    Joined:
    Sep 5, 2006
    Messages:
    848
    до тех пор, пока ты не знаешь что такое рекурсия - боюсь что никак...
     
  6. giskar

    giskar New Member

    Blog Posts:
    0
    Joined:
    Aug 2, 2007
    Messages:
    43
    спасибо всем, пожалуй совет на счёт рекурсивных процедур самый верный(уже читаю). А на счёт этих API функций, на которые все пачамут молятся, так я их как то не очень уважаю, хочется всё вручную делать, так понятнее:))
     
  7. nitrotoluol

    nitrotoluol New Member

    Blog Posts:
    0
    Joined:
    Sep 5, 2006
    Messages:
    848
    giskar
    Вручную - это как? при помощи компонентов? )))))))))
     
  8. cresta

    cresta Active Member

    Blog Posts:
    0
    Joined:
    Jun 13, 2004
    Messages:
    2,257
    хочется всё вручную делать

    дык напиши свой драйвер файловой системы и работай с ним, коль апи не устраивают :)
     
  9. nitrotoluol

    nitrotoluol New Member

    Blog Posts:
    0
    Joined:
    Sep 5, 2006
    Messages:
    848
    А это, чтобы проще осваивалось. Простой код рекурсивного поиска файла по винту.

    Code (Text):
    1. ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
    2. ; Global files search in MASM
    3. ;      Created by Ct757
    4. ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
    5. ;
    6. ; Use MASM to compile this shit
    7. ;
    8. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    9. ; В данном примере показана рекурсивная реализация
    10. ; поиска файлов на ассемблере под Windows с помощью
    11. ; API-функций FindFirstFile + FindNextFile, а так же
    12. ; показано как можно узнать список присутствующих
    13. ; в системе дисков с помощью функции GetLogicalDrives
    14. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    15.  
    16. .386
    17. .model flat, stdcall
    18.  
    19. option casemap:none
    20.  
    21. include \masm32\include\windows.inc
    22. include \masm32\include\kernel32.inc
    23. include \masm32\include\user32.inc
    24.  
    25. includelib \masm32\lib\user32.lib
    26. includelib \masm32\lib\kernel32.lib
    27.  
    28. .data                                                         ; Секция данных
    29.  
    30.       buf     db 500h dup(?)                                  ; Буффер для имени директории
    31.    
    32.       fake1   db '.',0                                        ; Директории, которые
    33.       fake2   db '..',0                                       ; НЕ надо сканировать
    34.  
    35. .code                                                         ; Секция кода
    36.  
    37. find_files proc                                               ; Рекурсивная процедура
    38.                                                               ; Поиска файлов
    39.  
    40.       push    ebp                                             ; Выделим место в стеке
    41.       mov     ebp,esp                                         ; под хэндл поиска
    42.       sub     esp,144h                                        ; и структуру WIN32_FIND_DATA
    43.  
    44.       lea     eax,[ebp-144h]                                  ; Вычисляем указатель на find_data
    45.       invoke  FindFirstFile,offset buf,eax                    ; Ищем файлы
    46.       inc     eax                                             ; Если ничего
    47.       je      exit                                            ; не нашли - выходим
    48.       dec     eax                                             ; Иначе, сохраним
    49.       mov     dword ptr [ebp-6h],eax                          ; хэндл поиска
    50.  
    51. find_next:
    52.       mov     eax,dword ptr [ebp-144h]                        ; Проверяем, нашли
    53.       and     eax,FILE_ATTRIBUTE_DIRECTORY                    ; директорию?
    54.       je      found                                           ; Если нет - прыгаем на found
    55.  
    56.       lea     eax,[ebp-118h]                                  ; Вычислим указатель на cFileName
    57.       invoke  lstrcmp,offset fake1,eax                        ; это "."?
    58.       test    eax,eax                                         ; Если да,
    59.       je      next                                            ; ищем дальше
    60.  
    61.       lea     eax,[ebp-118h]                                  ; Вычислим указатель на cFileName
    62.       invoke  lstrcmp,offset fake2,eax                        ; это ".."?
    63.       test    eax,eax                                         ; Если да,
    64.       je      next                                            ; ищем дальше
    65.  
    66.       invoke  lstrlen,offset buf                              ; Вычислим длину строки
    67.       sub     eax,3                                           ; Вычтем *.*
    68.       push    eax                                             ; Сохраним полученную длину
    69.  
    70.       mov     byte ptr [buf+eax],0                            ; Если мы всё-таки нашли
    71.       lea     eax,[ebp-118h]                                  ; директорию, то прибавим
    72.       invoke  lstrcat,offset buf,eax                          ; к её имени cFileName
    73.  
    74.       invoke  lstrlen,offset buf                              ; Вычислим длину строки
    75.  
    76.       mov     dword ptr [buf+eax],'*.*\'                      ; Прибавим \*.*
    77.       mov     byte ptr [buf+eax+4],0                          ; для поиска
    78.  
    79.       call    find_files                                      ; Вызываем процедуру поиска
    80.                                                               ; для найденной директории
    81.  
    82.       pop     eax                                             ; Восстановим дляну строки
    83.       mov     dword ptr [buf+eax-1],'*.*\'                    ; И восстановим \*.*
    84.       mov     byte ptr [buf+eax+3],0                          ;
    85.  
    86.       jmp     next                                            ; Ищем дальше
    87.  
    88. found:
    89.       lea     eax,[ebp-118h]                                  ; Вычислим длину
    90.       invoke  lstrlen,eax                                     ; cFileName
    91.       cmp     dword ptr [ebp-118h+eax-4],'txt.'               ; Проыерим расширение файла
    92.       jne     next                                            ; Если не равно ищем дальше
    93.  
    94.       lea     eax,[ebp-118h]                                  ; Если нашли, то что нужно
    95.       invoke  MessageBox,0,eax,eax,0                          ; Покажем MessageBox с именем файла
    96.  
    97. next:
    98.       lea     eax,[ebp-144h]                                  ; Вычислим указатель на find_data
    99.       invoke  FindNextFile,dword ptr [ebp-6h],eax             ; Ищем следующий файл
    100.       test    eax,eax                                         ;
    101.       jne     find_next                                       ; Если ничего не нашли
    102.  
    103.       invoke  FindClose,dword ptr [ebp-6h]                    ; Закрываем хэндл поиска
    104.  
    105. exit:
    106.       leave                                                   ; Выходим из
    107.       ret                                                     ; процедуры
    108. find_files endp
    109.  
    110. start:
    111.       invoke  SetErrorMode,SEM_FAILCRITICALERRORS             ; Установим error mode
    112.                                                               ; чтобы в случае обращения
    113.                                                               ; к недоступному диску
    114.                                                               ; не вываливалось сообщение
    115.  
    116.       invoke  GetLogicalDrives                                ; Получаем список дисков
    117.                                                               ; существующих в системе
    118.  
    119.       mov     ecx,25                                          ; Будем проверять, начиная с Z:\
    120.  
    121. find_drives:
    122.       mov     ebx,1                                           ; Нехитрые операции в
    123.       shl     ebx,cl                                          ; ходе которых мы выясняем
    124.       and     ebx,eax                                         ; присутсвует диск в
    125.       je      no_disk                                         ; системе или нет
    126.  
    127. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    128. ; На всякий случай, пояснение из MSDN:
    129. ;
    130. ; ;---------------------------------;
    131. ; ;  DWORD GetLogicalDrives(void);  ;
    132. ; ;---------------------------------;
    133. ;
    134. ; Return Values:
    135. ; --------------
    136. ;     If the function succeeds, the return value is a bitmask
    137. ;     representing the currently available disk drives.
    138. ;     Bit position 0 (the least-significant bit) is drive A,
    139. ;     bit position 1 is drive B, bit position 2 is drive C, and so on.
    140. ;
    141. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    142.  
    143.       add     cl,65                                           ; Если да, то
    144.       mov     byte ptr buf,cl                                 ; добавим букву
    145.       sub     cl,65                                           ; диска в буффер
    146.  
    147.       mov     dword ptr buf+1,'.*\:'                          ; Сформируем строку
    148.       mov     byte ptr buf+5,'*'                              ; для поиска, вида,
    149.       mov     byte ptr buf+6,0                                ; например, C:\*.*
    150.  
    151.       push    eax                                             ; Сохраняем нужные
    152.       push    ecx                                             ; регистры в стеке
    153.  
    154.       call    find_files                                      ; Вызываем процедуру поиска
    155.  
    156.       pop     ecx                                             ; Восстанавливаем
    157.       pop     eax                                             ; регистры
    158.  
    159. no_disk:                                                      ; Если диска нет,
    160.       dec     ecx                                             ; то проверяем следующий
    161.       jge     find_drives                                     ; пока ecx>0
    162.  
    163.       invoke  ExitProcess,0                                   ; Выходим из программы
    164. end start
     
  10. asmlamo

    asmlamo Well-Known Member

    Blog Posts:
    0
    Joined:
    May 18, 2004
    Messages:
    1,742
    Ну что такое рекурсия знают услужливые API функции :)
     
  11. asmlamo

    asmlamo Well-Known Member

    Blog Posts:
    0
    Joined:
    May 18, 2004
    Messages:
    1,742
    Как говорил один препод:

    Чтобы понять рекурсию нужно понять рукурсию :)
     
  12. Y_Mur

    Y_Mur Active Member

    Blog Posts:
    0
    Joined:
    Sep 6, 2006
    Messages:
    2,494
    Рекурсия в программировании - полный отстой - бесполезная трата тиков и замусоривание стека ;)
    Везде в программах следует заменять рекурсию циклом ;)
    Хотя в математике рекурся рулит, ну и ооочень редко может оказаться полезной где нибудь в специфических макросах.
     
  13. asmlamo

    asmlamo Well-Known Member

    Blog Posts:
    0
    Joined:
    May 18, 2004
    Messages:
    1,742
    Есть даже некая теорема которая говорит о том что любую рекурсию можно развернуть в цикл ...
     
  14. giskar

    giskar New Member

    Blog Posts:
    0
    Joined:
    Aug 2, 2007
    Messages:
    43
    В Юрове кстати говорится о том , что рекурсию по возможности лучше избегать, и применять циклы:lol:
     
  15. nitrotoluol

    nitrotoluol New Member

    Blog Posts:
    0
    Joined:
    Sep 5, 2006
    Messages:
    848
    Если задачу проще решить рекурсией - то я ее буду решать рекурсией, независимо от того, что говорит дядя Юров. Как пример - куда проще организовать поиск в субдиректориях через рекурсию, обход графа в глубину так же проще решается рекурсией, нежели через связанные списки.

    Y_Mur
    Часто лишние тики процессора позволяют сберечь уйму дополнительных стуков сердца и позволяет избежать замусоривания мозгов. Лишний часы моей жизни, сэкономленные на отладке - для меня это веский довод.
    Более того - грамотно организованная рекурсия никакого замусоривания не может вызвать в принципе.
     
  16. Mental_Mirror

    Mental_Mirror New Member

    Blog Posts:
    0
    Joined:
    May 7, 2007
    Messages:
    431
    Ну как известно любой алгоритм можно реализовать без рекурсии.
     
  17. Y_Mur

    Y_Mur Active Member

    Blog Posts:
    0
    Joined:
    Sep 6, 2006
    Messages:
    2,494
    nitrotoluol
    Вот и я о том же - хочешь сэкономить на отладке и улучшить читабельность программу всеми силами избегай рекурсий ;)
    Рекурсия может сэкономить строки в хай-левел программе, но ценой ухудшения исполнимого кода и читабельности/понимаемости проги ;)
    Ты в курсе что в твоём примере каждый самовызов добавляет в стек
    Code (Text):
    1.       push    ebp                                             ; Выделим место в стеке
    2.       mov     ebp,esp                                         ; под хэндл поиска
    3.       sub     esp,144h                                        ; и структуру WIN32_FIND_DATA
    хотя реально тебе нужна только одна копия?
    Кроме того стек забивается одинаковыми адресами возврата, что в общем-то мелочь, но кроме стека адресами возврата забивается механизм предсказания возвратов (из которого вытесняются полезные адреса) а это уже аукнется при дальнейшем исполнении программы.
    А когда основной цикл рекурсии прокртится начнётся второй цикл основанный на ret-ах, в котором чистится тот хламник что накопился в основном цикле, конечно можно приспособить этот дополнительный цикл на что-то полезное, но проще обойтись без этого гемороя, правильно построив алгоритм ;)
     
  18. giskar

    giskar New Member

    Blog Posts:
    0
    Joined:
    Aug 2, 2007
    Messages:
    43
    товарищи! вот здесь nitrotoluol привён код поиска файла. Он у меня почему то при ассемблировании выдаёт ошибку:
    ассемблирую: ml.exe dd.asm
    в итоге при линковании выдаётся ошибка:"fatal error L1104: \masm32\lib\user32.lib: not valid library" (это он про includelib \masm32\lib\user32.lib)

    подозреваю что то же он скажет и про includelib \masm32\lib\kernel32.lib

    объясните что такое происходит. спасибо.
     
  19. RamMerLabs

    RamMerLabs Well-Known Member

    Blog Posts:
    0
    Joined:
    Sep 11, 2006
    Messages:
    1,426
    компилят вообще-то так:
    ну и на всякий случай: линкуют так:

     
  20. rain

    rain New Member

    Blog Posts:
    0
    Joined:
    Apr 22, 2006
    Messages:
    976
    просто вспомнилась фраза по поводу "Итерация подобна человеку, рекурсия - Богу"
    я тоже не против и за рекурсию, но обход файлов имхо лучше делать через неё, кстати за примером далеко ходить не нужно в стандартной поставке масм есть закоментированный экзапл называется findfile (хотя приведённый веше сорец тоже на первый взгляд неплох). Кстати имхо эта рекурсия в данном случае куда красивее смотрится на стандартных макросах .if/.endif с отодвиганием вложенного кода вправо как это принята в яву. Когда-то писал, но сорец кажется канул в лету