Einzelnen Beitrag anzeigen

Dax
(Gast)

n/a Beiträge
 
#2

Re: Bitte Assembler-Routine verbessern

  Alt 23. Dez 2007, 20:30
Delphi-Quellcode:
function CharPos_JOH_SSE2_1_b(Ch : Char; const Str : AnsiString; aStart : Integer = 1) : Integer;
asm
  test edx, edx
  jz @@NullString
  mov esi, ecx
  dec esi
  mov ecx, [edx-4]
  cmp esi, ecx
  jle @@Continue
  xor eax, eax
  ret
  
@@Continue:
  add ecx, esi
  add edx, esi
  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;
Ich hab kein Delphi, um es zu testen.. Aber ich vermute, dass es so läuft. Was ich hier tue, entspricht weitgehend deiner Vermutung: am Anfang sagen wir einfach, dass der String aStart Zeichen kürzer ist als tatsächlich und setzen den Anfang des Strings (für die Funktion) auf das Zeichen bei aStart.
  Mit Zitat antworten Zitat