На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Все статьи должны быть оформлены согласно Правил оформления статей.
2. Любые обсуждения должны происходить в специальной теме, обсуждение в любых других темах раздела запрещены.
3. Запрещается писать статьи о создании и распространении вирусов, троянов и других вредоносных программ!
4. За грамотно написанные и правильно оформленные статьи авторы награждаются DigiMoney.

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > Поиск строки с использование SCAS, FASM, Win, Общие вопросы
       
      Поиск строки и подстроки с использование команды SCAS

      EDI- адрес области памяти, в которой совершается поиск
      AL(AX)(EAX)-искомый байт(слово)(двойное слово)
      ECX – при использовании префиксов ret/rep, количество байт(слов)(двойных слов) с которыми будет выполнятся
      REPNZ SCASB(SCASW)(SCASD)
      JNZ NOFOUND в случае если данные не найдены переходим на метку

      Теперь несколько примеров использования (компилятор FASM):

      ПОИСК ДВОЙНОГО СЛОВА В СТРОКЕ
      ДО ПЕРВОГО СОВПАДЕНИЯ

      ExpandedWrap disabled
        include 'win32ax.inc'
        .data
        dat_str db 'Привет всем людям этой планеты!!!',0
        ADR dd dat_str
        .code
          start:
                cld ; сбросим флаг направления, направление поиска от младших адресов к старшим
                mov edi,[ADR]
                invoke  lstrlen,dat_str
                mov ecx,eax ; длина строки
                mov eax,'людя'; элемент
                repnz scasd
                jnz Err
        ; если нашли подстроку, то
              mov dword[edi-4],'ЛЮДЯ'
              invoke  MessageBox,HWND_DESKTOP,"Найден","",MB_OK
              invoke  MessageBox,HWND_DESKTOP,dat_str,"",MB_OK
              jmp Ext
         
           Err:
           invoke  MessageBox,HWND_DESKTOP,"Не найден","",MB_OK
         
           Ext:
           invoke  ExitProcess,0
        .end start

      ПОИСК ВСЕХ БАЙТОВ В СТРОКЕ

      ExpandedWrap disabled
        include 'win32ax.inc'
        .data
        dat_str db 'карл у клары украл коралы ',0
        ADR dd dat_str
        .code
          start:
                cld
                mov edi,[ADR]
                invoke  lstrlen,[ADR]
                mov ecx,eax ; длина строки
                mov eax,'а'; элемент
                NXT:
                repnz scasb
                jnz EN
                mov byte[edi-1],'А'
                cmp ecx,0
                jne NXT
                EN:
                invoke  MessageBox,HWND_DESKTOP,dat_str,"",MB_OK
                invoke  ExitProcess,0
        .end start

      ПРОЦЕДУРА ПОИСКА СТРОКИ

      ExpandedWrap disabled
        proc search,_baseadr,_stradr,_basel,_strl
        pushad
        cld
        push [_strl]
        push [_stradr]
        call UpCases
        mov edi,[_baseadr]      ; адрес базовой строки
        .NXTSE:
        mov esi,[_stradr]       ; адрес искомой строки
        mov ecx,[_basel]
        mov al,byte[esi]; элемент
        repnz scasb
        jnz .SEARTH_ERROR
        dec edi
        mov esi,[_stradr]
        mov ecx,[_strl]         ; длина строки
        repe cmpsb
        jnz .NXTSE
        mov eax,edi
        sub eax,[_strl]
        mov [resylt],eax
        jmp .EXT
        ;Строка найденна
        .SEARTH_ERROR:
        mov [resylt],0
        .EXT:
        popad
        mov eax,[resylt]
        ret
        resylt dd 0
        endp

      Прикреплённый файлПрикреплённый файлSCAS.rar (1.65 Кбайт, скачиваний: 257)
      Что чайнику - варежка с дырками, то мастеру - перчатка без пальцев.
        Я извиняюсь, но первый пример ("ПОИСК ДВОЙНОГО СЛОВА...") несостоятелен.

        Строковые команды с суффиксом D (например, SCASD) изменяют значения индексных регистров на 4, а не на 1. Так что в данном примере подстрока найдется только в том случае, если ее позиция в строке кратна 4. В данном случае позиция подстроки - 12, так что она найдется на четвертом шаге. Но если, например, убрать из строки слово "всем" с пробелом, то ничего не выйдет.
          Цитата
          Я извиняюсь, но первый пример ("ПОИСК ДВОЙНОГО СЛОВА...") несостоятелен.

          Всё правельно посик ДВОЙНОГО СЛОВА в строке из ДВОЙНЫХ СЛОВ.
          Что чайнику - варежка с дырками, то мастеру - перчатка без пальцев.
            Fasmw 1.69.14
            Error: Invalid operand
            Istruction: enter
            Source: search.inc [3]
            --
            там и метка Err недопустимая, впрочем я ламер, может что я не понял.
            Сообщение отредактировано: semiono -
            xchg eax,eax
              Гм. Так никто и не отозвался, что ль?
              semiono, попробуй добавить директиву типа процессора в начало. Например .386, ибо код 32-битный. Инструкции ENTER, как и LEAVE, не было в исходном наборе 8086/88. Видимо код из примера рассчитан на компилятор, который изначально предусматривает компиляцию под 386 или позднее.
              Впрочем, у ENTER два параметра. Хм. Мож это не инструкция, а макрос?
              Одни с годами умнеют, другие становятся старше.
                Не, не поможет. Сорсы, судя по всему, под фасм. В нем же нет директив типа процессора и набор инструкций под конкретный процессор программист обязан контролировать сам.
                Но проблема не в этом. Судя по контексту ENTER является каким то макросом (иначе где обязательные два параметра?), в паре с RETURN. И либо это макросы из набора древнего фасма, либо автор просто забыл их выложить.
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script Execution time: 0,1341 ]   [ 17 queries used ]   [ Generated: 18.08.18, 00:37 GMT ]