Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Получить позицию последнего вхождения подстроки в строку 2

Delphi , Синтаксис , Текст и Строки

Получить позицию последнего вхождения подстроки в строку 2

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

 // by Manuel Wiersch 

 function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt;
 asm
         TEST    EAX,EAX         // EAX auf 0 prufen (d.h. SubStr = nil) 
        JE      @@noWork        // wenn EAX = 0 dann Sprung zu noWork 
        TEST    EDX,EDX
         // Test ob S = nil 
        JE      @@stringEmpty   // bei Erfolg -> Sprung zum Label 'stringEmpty' 
        PUSH    EBX
         PUSH    ESI
         PUSH    EDI             // Register auf dem Stack sichern  Grund: OH 
                                // OH: "In einer asm-Anweisung mu? der Inhalt 
                                // der Register EDI, ESI, ESP, EBP und EBX 
                                // erhalten bleiben (dh. vorher auf dem Stack 
                                // speichern)         MOV     ESI, EAX 
                                // ESI = Sourceindex      -> Adresse vom SubStr 
        MOV     EDI, EDX        // EDI = Destinationindex -> Adresse von S 
        MOV     ECX,[EDI-4]     // Lange von S  ins Zahlregister 
        MOV     EDX,[ESI-4]     // Lange des SubStr in EDX 
        DEC     EDX             // Length(SubStr) - 1 
        JS      @@fail
         // Vorzeichenbedingter Sprung (JumpIfSign) 
                                // d.h. (EDX < 0) -> Sprung zu 'fail' 
        STD;                    // SetDirectionFlag -> Stringroutinen von hinten 
                                // abarbeiten 
        ADD     ESI, EDX        // Pointer auf das letzte Zeichen vom SubStr 
        ADD     EDI, ECX
         DEC     EDI             // Pointer auf das letzte Zeichen von S 
        MOV     AL, [ESI]       // letztes Zeichen des SubStr in AL laden 
        DEC     ESI             // Pointer auf das vorletzte Zeichen setzen. 
        SUB     ECX, EDX        // Anzahl der Stringdurchlaufe 
                                // = Length(s) - Length(substr) + 1 
        JLE     @@fail          // Sprung zu 'fail' wenn ECX <= 0 
@@loop:
         REPNE   SCASB           // Wdh. solange ungleich (repeat while not equal) 
                                // scan string for byte 
        JNE     @@fail
         MOV     EBX,ECX         { Zahleregister, ESI und EDI sichern, da nun der 
                                  Vergleich durchgefuhrt wird ob die nachfolgenden 
                                  Zeichen von SubStr in S vorhanden sind }
         PUSH    ESI
         PUSH    EDI
         MOV     ECX,EDX         // Lange des SubStrings in ECX 
        REPE    CMPSB           // Solange (ECX > 0) und (Compare string fo byte) 
                                // dh. solange S[i] = SubStr[i] 
        POP     EDI
         POP     ESI             // alten Source- und Destinationpointer vom Stack holen 
        JE      @@found         // Und schon haben wir den Index da ECX = 0 
                                // dh. alle Zeichen wurden gefunden 
        MOV     ECX, EBX        // ECX wieder auf alte Anzahl setzen und 
        JMP     @@loop          // Start bei 'loop' 
@@fail:
         XOR     EAX,EAX         // EAX auf 0 setzen 
        JMP     @@exit @@stringEmpty:
         XOR     EAX,EAX
         JMP     @@noWork @@found:
         MOV     EAX, EBX        // in EBX steht nun der aktuelle Index 
        INC     EAX             // um 1 erhohen, um die Position des 1. Zeichens zu 
                                // bekommen 
@@exit:
         POP     EDI
         POP     ESI
         POP     EBX
 @@noWork:         CLD;          // DirectionFlag loschen 
end;

Here's a translation of the content into Russian:

Функция LastPos на языке Delphi, написанная в ассемблере, ищет последнее вхождение подстроки SubStr в строке S. Вот подробное описание ее работы:

Сигнатура функции

function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt;

Функция принимает два параметра: SubStr (подстрока, которую нужно найти) и S (оригинальная строка). Она возвращает позицию последнего вхождения SubStr в S.

Ассемблерный код

@@noWork:
    TEST    EAX, EAX           // Проверка, является ли SubStr nil
    JE        @@stringEmpty     // Если так, прыгнуть к 'stringEmpty'
    PUSH    EBX
    PUSH    ESI
    PUSH    EDI               // Сохранить регистры на стеке

    MOV     ESI, EAX          // Установка ESI в адрес SubStr
    MOV     EDI, EDX          // Установка EDI в адрес S
    MOV     ECX, [EDI-4]       // Получение длины S в ECX
    MOV     EDX, [ESI-4]       // Получение длины SubStr в EDX
    DEC     EDX               // Уменьшение EDX (Длина(SubStr) - 1)

    JS        @@fail           // Если EDX отрицательный, прыгнуть к 'fail'

    STD;                      // Установка флага направления для строковых операций

    ADD     ESI, EDX          // Установка указателя на последний символ SubStr
    ADD     EDI, ECX
    DEC     EDI               // Установка указателя на последний символ S

    MOV     AL, [ESI]         // Загрузка последнего символа SubStr в AL
    DEC     ESI               // Установка указателя на предыдущий символ

    SUB     ECX, EDX          // Рассчет количества итераций строки
    JLE       @@fail            // Если ECX <= 0, прыгнуть к 'fail'

@@loop:
    REPNE   SCASB             // Повторять до не равенства (сканирование строки для байта)
    JNE       @@fail

    MOV     EBX, ECX           // Сохранение регистров на стеке
    PUSH    ESI
    PUSH    EDI
    MOV     ECX, EDX           // Получение длины SubStr в ECX

    REPE    CMPSB             // Сравнение строки для байта (до ECX == 0)
    POP     EDI
    POP     ESI               // Восстановление исходного источника и целевого указателей

    JE        @@found           // Если все символы совпали, прыгнуть к 'found'

    MOV     ECX, EBX          // Reset ECX to the saved value
    JMP       @@loop            // Начать заново с начала цикла

@@fail:
    XOR     EAX, EAX           // Установка EAX в 0 (неудача)

    JMP       @@exit           // Выход с неудачей

@@stringEmpty:
    XOR     EAX, EAX           // Установка EAX в 0 (пустая строка)
    JMP       @@noWork          // Выход без поиска

@@found:
    MOV     EAX, EBX          // Хранение позиции последнего вхождения
    INC     EAX               // Увеличение EAX для получения правильной позиции

@@exit:
    POP     EDI
    POP     ESI
    POP     EBX

@@noWork:
    CLD;                      // Очистка флага направления

Вот шаг за шагом объяснение работы функции:

  1. Если SubStr является nil, прыгнуть к 'stringEmpty'.
  2. Сохранить регистры на стеке.
  3. Установка ESI в адрес SubStr и EDI в адрес S.
  4. Получение длин SubStr и S в ECX и EDX соответственно.
  5. Уменьшение EDX для получения длины SubStr минус 1 (используется позднее).
  6. Если EDX отрицательный, прыгнуть к 'fail'.
  7. Установка флага направления для строковых операций STD;.
  8. Рассчет позиции последнего символа SubStr и установка ESI соответственно.
  9. Повторение цикла до ECX <= 0:
    • Сканирование строки для байта, совпадающего с первым символом SubStr.
    • Если найден совпадок, повторить цикл с оставшимися символами SubStr.
  10. Если все символы SubStr совпали, прыгнуть к 'found'. Иначе, установка EAX в 0 и выход.
  11. В 'found', хранение позиции последнего вхождения в EAX и увеличение ее на 1.
  12. Выход с успехом.

Функция quite сложна, но я надеюсь, что это объяснение поможет вам понять ее поведение!

Функция LastPos на языке Delphi ищет позицию последнего вхождения подстроки в строку.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Текст и Строки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 13:17:23/0.0061931610107422/1