Deine
ASM-Routine liefern bei mir imm nur 0, wird aber an dem alten Delphi liegen (
BDS 2006)
Da waren Strings noch 1 Byte per Char.
Ab Delphi 9 (soweit ich weiß) 2 Bytes per Char.
Die Größe der Chars ist in der Funktion im Prinzip schon durch die Konstante sz (Size) berücksichtigt, aber ich hatte nicht daran gedacht, das auch bei dem Zeichenvergleich zu berücksichtigen. Dort muss ax in al geändert werden.
Die nachstehende Funktion sollte mit den 1 Byte Chars funktionieren. (konnte ich aber nicht testen)
Für 2 Byte Chars muss das {$DEFINE
ANSI} auskommentiert werden.
Weiß jemand ob/wie man das automatisieren kann?
Delphi-Quellcode:
FUNCTION CountStr(
const SearchFor,SearchIn:
string):Integer;
{$DEFINE ANSI}
const sz=SizeOf(Char);
asm
test eax,eax
je @Ret
// SearchFor leer
mov ecx,[eax-4]
// Length(SearchFor)
push ebp
push ebx
push edi
push esi
push 0
// Anzahl Zeichen
test edx,edx
je @
End // SearchIn leer
mov ebp,ecx
// Length(SearchFor)
mov ebx,[edx-4]
// Length(SearchIn)
sub ebx,ecx
// Length(SearchIn)-Length(SearchFor)
jc @
End // SearchFor länger als SearchIn
lea esi,[eax+ecx*sz]
// Hinter SearchFor
lea edi,[edx+ecx*sz]
// Hinter SearchIn[Length(SearchFor)]
neg ecx
jmp @Entry
@NextStart: sub ebx,1
jc @
End // Alles durchsucht
add edi,sz
// Nächste Startposition
@Entry: mov edx,ecx
// Count
@CharLoop:
{$IFDEF ANSI}
mov al,[esi+edx*sz]
// SearchFor[edx]
cmp al,[edi+edx*sz]
// SearchIn[edx]
{$ELSE}
mov ax,[esi+edx*sz]
// SearchFor[edx]
cmp ax,[edi+edx*sz]
// SearchIn[edx]
{$ENDIF}
jne @NextStart
@NextChar: add edx,1
// Count
jl @CharLoop
// nächstes Zeichen prüfen
add [esp],1
// Anzahl Fundstellen
lea edi,[edi+ebp*sz]
// Um Length(SearchFor) weiter
sub ebx,ebp
// Anzahl verfügbarer Zeichen
jnc @Entry
// Noch Zeichen da
@
End: pop eax
// Anzahl Zeichen
pop esi
pop edi
pop ebx
pop ebp
@Ret:
end;