Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.062 Beiträge
 
Delphi XE2 Professional
 
#30

AW: Boyer Moore Algorithmus

  Alt 8. Jun 2013, 02:54
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;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat