{1.}
{
Letzte Position von SubStr in S ermitteln.
Returns the last occurence of SubStr in S.
}
function LastPos(SubStr, S: string): Integer; var Found, Len, Pos: integer; begin Pos := Length(S);
Len := Length(SubStr);
Found := 0; while (Pos > 0) and (Found = 0) do
begin
if Copy(S, Pos, Len) = SubStr then Found := Pos;
Dec(Pos); end;
LastPos := Found; end;
{*************************************************************}
// by Manuel Wiersch
{2.} function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt; asm TEST EAX,EAX // EAX auf 0 prüfen (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] // Länge von S ins Zählregister MOV EDX,[ESI-4] // Länge 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 Stringdurchläufe
// = 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 { Zähleregister, ESI und EDI sichern, da nun der
Vergleich durchgeführt wird ob die nachfolgenden
Zeichen von SubStr in S vorhanden sind } PUSH ESI
PUSH EDI
MOV ECX,EDX // Länge 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 erhöhen, um die Position des 1. Zeichens zu
// bekommen @@exit:
POP EDI
POP ESI
POP EBX
@@noWork: CLD; // DirectionFlag löschen end;