Сравнение строки обратно с STD - бага

Тема в разделе "WASM.ASSEMBLER", создана пользователем AQSW, 7 июл 2009.

  1. AQSW

    AQSW New Member

    Публикаций:
    0
    Регистрация:
    7 июл 2009
    Сообщения:
    4
    Нужно сравнить строки в обратной последовательности, не работает код. Не знаю где копать :dntknw:

    --------
    Function CompareStr_Back(const pStrA,pStrB;Length:integer):boolean;
    asm
    PUSH ESI // сохраним регистры
    PUSH EDI
    MOV ESI,EAX
    MOV EDI,EDX
    ADD EDI,Length // поставим смещение на конец строки
    ADD ESI,Length
    MOV ECX,Length // СЧЕТЧИК
    SHR ECX,2 // что бы сравнивать 4 байтами
    XOR EAX,EAX
    STD // флаг DF=1
    REPE CMPSD
    CLD // обратно флаг
    JNE @EXIT
    MOV EAX,1
    @EXIT
    POP EDI
    POP ESI
    end;
    --------
    PS: Знаю, что нужно еще остаток проверять, этот код применый.
    Если длинные строки, то не правильное сравнение, хоть тресни :dntknw:
    слева-направо нормально, а права на лево глюк. :dntknw:
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Код (Text):
    1.    ADD  EDI,Length  // поставим смещение на конец строки
    2.    ADD  ESI,Length
    3.    sub edi,4
    4.    sub esi,4
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Если это паскалевский register-вызов, то Length передается в ECX:
    Код (Text):
    1. lea edi,[edi+ecx-4]
    2. lea esi,[esi+ecx-4]
    3. shr ecx,2
     
  4. tyug

    tyug New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2008
    Сообщения:
    19
    ?
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Тогда уж сразу
    lea edi,[eax+ecx-4]
    lea esi,[edx+ecx-4]

    tyug
    это у него true/false результат так возвращается, а ":" потеряно скорее всего очепятка.
     
  6. AQSW

    AQSW New Member

    Публикаций:
    0
    Регистрация:
    7 июл 2009
    Сообщения:
    4
    sub edi,4 - не помогает :dntknw:

    Почему Count не через, EAX, там у меня больше параметров и Length на стеке находится
    у меня параметры реальные:
    (const pStrA,pStrB;OfsA.OfsB,Length:integer):boolean;
    где делается
    ADD EDI,OfsA
    ADD ESI,OfsB

    ADD EDI,Count я привел для простоты


    Это не полный код из исходника, а написанный руками.
    MOV EAX,1 // булевское True
    @EXIT: // тут двоеточее дб
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    AQSW
    Ну и зря ;)
    Код (Text):
    1. Проще объявить
    2. function  CompareStr_Back(pFromA,pFromB:pChar;Len:integer):boolean;register;
    3. и вызывать
    4. CompareStr_Back(pChar(pStrA)+OffsA,pChar(pStrB)+OffsB,Len);
    И вообще, лучше привести полный код, а не "1 пишем, 2 в уме", т.к. ошибка м.б. и именно в этом "уме" :)
     
  8. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Вобщем-то отладчик спасёт как всегда.
     
  9. je_

    je_ New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    143
    неправильно так делать REP CMPSD, если неизвестна длина.
    делайте REP CMPSB.

    Код (Text):
    1. PUSH ESI // сохраним регистры
    2. PUSH EDI
    3.    MOV  ESI,EAX
    4.    MOV  EDI,EDX
    5.    MOV ECX,Length // СЧЕТЧИК
    6.  
    7.  XOR EAX,EAX
    8. TEST ecx ecx
    9. JLE @EXIT
    10. LEA EDI, D$edi+ecx-1 // поставим смещение на конец строки
    11. LEA  ESI, D$esi+ecx-1
    12.  
    13.     STD // флаг DF=1
    14.    REPE CMPSD
    15.     CLD // обратно флаг
    16. SETZ AL
    17. @EXIT:
    18.    POP EDI
    19.    POP ESI
    20. endp;
     
  10. je_

    je_ New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    143
    забыл исправить REPE CMPSB
     
  11. AQSW

    AQSW New Member

    Публикаций:
    0
    Регистрация:
    7 июл 2009
    Сообщения:
    4
    Согласен, но когда пихаешь, все что под руку попадется (разные типы), то закалебывает писать эту арифметику в скобках с ^.
    А на счет кода, на машине которой все кодится нет инета, а руками переписывать вломы.


    В общем фишка была в том, что при CMPSD указатель в EDI, дб на первом символе (слева-направо), т.к. это DWord, а при CMPSD на последнем символе.

    Так что был прав:
    Усе заработало.
    Тест я неиспользовал, т.к. в ECX нули будут после сдвига и CMPSD выполнятся не будет, а после

    REPE CMPSD
    JNE @EXIT
    я добавил:
    ADD ESI,3
    ADD EDI,3
    MOV ECX,EDX // В EDX нах-ся остаток DWord: MOV EDX,Length AND EDX,3
    REPE CMPSB // смотрим в остатке
    JNE @EXIT

    PS: Спасибо коллеги за участие. Усе получилось!!!
     
  12. je_

    je_ New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    143
    не веритцо как_та