скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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



Оформил: DeeCo

 // 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;





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook