(Moderator)
Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
Delphi 2007 Enterprise
|
Bitte Assembler-Routine verbessern
23. Dez 2007, 19:44
Hier habe ich eine Routine vom FastCode-Project, das nach einem einzelnen Zeichen in einem String sucht. Nix besonderes, nur eben sauschnell. Leider fängt die Routine immer vorne an. Ich hätte gerne einen dritten Parameter (wie bei PosEx), bei dem die Funktion dann anfängt zu suchen. Leider kann ich kein Asm. Kann mir jemand helfen?
Hier die Routine:
Delphi-Quellcode:
function CharPos_JOH_SSE2_1_b(Ch : Char; const Str : AnsiString) : Integer;
asm
test edx, edx
jz @@NullString
mov ecx, [edx-4]
push ebx
mov ebx, eax
cmp ecx, 16
jl @@Small
@@NotSmall:
mov ah, al {Fill each Byte of XMM1 with AL}
movd xmm1, eax
pshuflw xmm1, xmm1, 0
pshufd xmm1, xmm1, 0
@@First16:
movups xmm0, [edx] {Unaligned}
pcmpeqb xmm0, xmm1 {Compare First 16 Characters}
pmovmskb eax, xmm0
test eax, eax
jnz @@FoundStart {Exit on any Match}
cmp ecx, 32
jl @@Medium {If Length(Str) < 32, Check Remainder}
@@Align:
sub ecx, 16 {Align Block Reads}
push ecx
mov eax, edx
neg eax
and eax, 15
add edx, ecx
neg ecx
add ecx, eax
@@Loop:
movaps xmm0, [edx+ecx] {Aligned}
pcmpeqb xmm0, xmm1 {Compare Next 16 Characters}
pmovmskb eax, xmm0
test eax, eax
jnz @@Found {Exit on any Match}
add ecx, 16
jle @@Loop
pop eax {Check Remaining Characters}
add edx, 16
add eax, ecx {Count from Last Loop End Position}
jmp dword ptr [@@JumpTable2-ecx*4]
nop
nop
@@NullString:
xor eax, eax {Result = 0}
ret
nop
@@FoundStart:
bsf eax, eax {Get Set Bit}
pop ebx
inc eax {Set Result}
ret
nop
nop
@@Found:
pop edx
bsf eax, eax {Get Set Bit}
add edx, ecx
pop ebx
lea eax, [eax+edx+1] {Set Result}
ret
@@Medium:
add edx, ecx {End of String}
mov eax, 16 {Count from 16}
jmp dword ptr [@@JumpTable1-64-ecx*4]
nop
nop
@@Small:
add edx, ecx {End of String}
xor eax, eax {Count from 0}
jmp dword ptr [@@JumpTable1-ecx*4]
nop
@@JumpTable1:
dd @@NotFound, @@01, @@02, @@03, @@04, @@05, @@06, @@07
dd @@08, @@09, @@10, @@11, @@12, @@13, @@14, @@15, @@16
@@JumpTable2:
dd @@16, @@15, @@14, @@13, @@12, @@11, @@10, @@09, @@08
dd @@07, @@06, @@05, @@04, @@03, @@02, @@01, @@NotFound
@@16:
add eax, 1
cmp bl, [edx-16]
je @@Done
@@15:
add eax, 1
cmp bl, [edx-15]
je @@Done
@@14:
add eax, 1
cmp bl, [edx-14]
je @@Done
@@13:
add eax, 1
cmp bl, [edx-13]
je @@Done
@@12:
add eax, 1
cmp bl, [edx-12]
je @@Done
@@11:
add eax, 1
cmp bl, [edx-11]
je @@Done
@@10:
add eax, 1
cmp bl, [edx-10]
je @@Done
@@09:
add eax, 1
cmp bl, [edx-9]
je @@Done
@@08:
add eax, 1
cmp bl, [edx-8]
je @@Done
@@07:
add eax, 1
cmp bl, [edx-7]
je @@Done
@@06:
add eax, 1
cmp bl, [edx-6]
je @@Done
@@05:
add eax, 1
cmp bl, [edx-5]
je @@Done
@@04:
add eax, 1
cmp bl, [edx-4]
je @@Done
@@03:
add eax, 1
cmp bl, [edx-3]
je @@Done
@@02:
add eax, 1
cmp bl, [edx-2]
je @@Done
@@01:
add eax, 1
cmp bl, [edx-1]
je @@Done
@@NotFound:
xor eax, eax
pop ebx
ret
@@Done:
pop ebx
end;
Und hier meine gewünschte Funktionsdeklaration
function CharPos_JOH_SSE2_1_b(Ch : Char; const Str : AnsiString; aStart : Integer = 1) : Integer;
Ich glaube, ich müsste nur zu der Adresse von 'Str' den Wert (aStart-1) hinzuaddieren und am Ende den Stack besser aufräumen, aber wie das geht weiss ich nicht.
Na? Erweicht sich ein Asm-Guru, mir die Routine anzupassen?
Frohes Fest an alle!
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
|