⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastcodepos.pas

📁 最快的Delphi快速处理源代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit FastCodePos;

(* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Fastcode
 *
 * The Initial Developer of the Original Code is Fastcode
 *
 * Portions created by the Initial Developer are Copyright (C) 2002-2005
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 * Charalabos Michael <chmichael@creationpower.com>
 * John O'Harrow <john@elmcrest.demon.co.uk>
 *
 * ***** END LICENSE BLOCK ***** *)

interface

{$I FastCode.inc}

type
  FastCodePosFunction = function(const SubStr: AnsiString; const Str: AnsiString): Integer;

{Functions shared between Targets}
function FastCodePosRTL    (const SubStr: AnsiString; const Str: AnsiString): Integer;
function FastCodePosBlended(const SubStr: AnsiString; const Str: AnsiString): Integer;
function FastCodePosXP     (const SubStr: AnsiString; const Str: AnsiString): Integer;
{Functions not shared between Targets}
function FastCodePosP4N   (const SubStr: AnsiString; const Str: AnsiString): Integer;
function FastCodePosPMD   (const SubStr: AnsiString; const Str: AnsiString): Integer;
function FastCodePosPascal(const SubStr: AnsiString; const Str: AnsiString): Integer;


const
  Version = '0.3';

  FastCodePosP4P  : FastCodePosFunction = FastCodePosBlended;
  FastCodePosPMB  : FastCodePosFunction = FastCodePosBlended;
  FastCodePosAMD64: FastCodePosFunction = FastCodePosXP;

function PosStub(const substr: AnsiString; const s: AnsiString): Integer;

implementation

//Author:            Aleksandr Sharahov
//Optimized for:     Intel P4 Prescott
//Instructionset(s): IA32
//Original name:     PosShaAsm4

function FastCodePosRTL(const SubStr: AnsiString; const Str: AnsiString): Integer;
asm
       push  ebx
       push  esi
       add   esp, -16
       test  edx, edx
       jz    @NotFound
       test  eax, eax
       jz    @NotFound
       mov   esi, [edx-4] //Length(Str)
       mov   ebx, [eax-4] //Length(Substr)
       cmp   esi, ebx
       jl    @NotFound
       test  ebx, ebx
       jle   @NotFound
       dec   ebx
       add   esi, edx
       add   edx, ebx
       mov   [esp+8], esi
       add   eax, ebx
       mov   [esp+4], edx
       neg   ebx
       movzx ecx, byte ptr [eax]
       mov   [esp], ebx
       jnz   @FindString

       sub   esi, 2
       mov   [esp+12], esi

@FindChar2:
       cmp   cl, [edx]
       jz    @Matched0ch
       cmp   cl, [edx+1]
       jz    @Matched1ch
       add   edx, 2
       cmp   edx, [esp+12]
       jb    @FindChar4
       cmp   edx, [esp+8]
       jb    @FindChar2
@NotFound:
       xor   eax, eax
       jmp   @Exit0ch

@FindChar4:
       cmp   cl, [edx]
       jz    @Matched0ch
       cmp   cl, [edx+1]
       jz    @Matched1ch
       cmp   cl, [edx+2]
       jz    @Matched2ch
       cmp   cl, [edx+3]
       jz    @Matched3ch
       add   edx, 4
       cmp   edx, [esp+12]
       jb    @FindChar4
       cmp   edx, [esp+8]
       jb    @FindChar2
       xor   eax, eax
       jmp   @Exit0ch

@Matched2ch:
       add   edx, 2
@Matched0ch:
       inc   edx
       mov   eax, edx
       sub   eax, [esp+4]
@Exit0ch:
       add   esp, 16
       pop   esi
       pop   ebx
       ret

@Matched3ch:
       add   edx, 2
@Matched1ch:
       add   edx, 2
       xor   eax, eax
       cmp   edx, [esp+8]
       ja    @Exit1ch
       mov   eax, edx
       sub   eax, [esp+4]
@Exit1ch:
       add   esp, 16
       pop   esi
       pop   ebx
       ret

@FindString4:
       cmp   cl, [edx]
       jz    @Test0
       cmp   cl, [edx+1]
       jz    @Test1
       cmp   cl, [edx+2]
       jz    @Test2
       cmp   cl, [edx+3]
       jz    @Test3
       add   edx, 4
       cmp   edx, [esp+12]
       jb    @FindString4
       cmp   edx, [esp+8]
       jb    @FindString2
       xor   eax, eax
       jmp   @Exit1

@FindString:
       sub   esi, 2
       mov   [esp+12], esi
@FindString2:
       cmp   cl, [edx]
       jz    @Test0
@AfterTest0:
       cmp   cl, [edx+1]
       jz    @Test1
@AfterTest1:
       add   edx, 2
       cmp   edx, [esp+12]
       jb    @FindString4
       cmp   edx, [esp+8]
       jb    @FindString2
       xor   eax, eax
       jmp   @Exit1

@Test3:
       add   edx, 2
@Test1:
       mov   esi, [esp]
@Loop1:
       movzx ebx, word ptr [esi+eax]
       cmp   bx, word ptr [esi+edx+1]
       jnz   @AfterTest1
       add   esi, 2
       jl    @Loop1
       add   edx, 2
       xor   eax, eax
       cmp   edx, [esp+8]
       ja    @Exit1
@RetCode1:
       mov   eax, edx
       sub   eax, [esp+4]
@Exit1:
       add   esp, 16
       pop   esi
       pop   ebx
       ret

@Test2:
       add   edx,2
@Test0:
       mov   esi, [esp]
@Loop0:
       movzx ebx, word ptr [esi+eax]
       cmp   bx, word ptr [esi+edx]
       jnz   @AfterTest0
       add   esi, 2
       jl    @Loop0
       inc   edx
@RetCode0:
       mov   eax, edx
       sub   eax, [esp+4]
       add   esp, 16
       pop   esi
       pop   ebx
end;

//Author:            Aleksandr Sharahov
//Optimized for:     Intel P4 Northwood
//Instructionset(s): IA32
//Original name:     PosShaAsm3

function FastCodePosBlended(const SubStr: AnsiString; const Str: AnsiString): Integer;
asm
       push  ebx
       push  esi
       add   esp, -16
       test  eax, eax
       jz    @NotFound
       test  edx, edx
       jz    @NotFound
       mov   ebx, [eax-4]
       mov   esi, [edx-4]
       cmp   esi, ebx
       jl    @NotFound
       test  ebx, ebx
       jle   @NotFound
       dec   ebx
       add   esi, edx
       add   edx, ebx
       mov   [esp+8], esi
       add   eax, ebx
       mov   [esp+4], edx
       neg   ebx
       movzx ecx, byte ptr [eax]
       mov   [esp], ebx
       jnz   @FindString

       sub   esi, 2
       mov   [esp+12], esi

@FindChar2:
       cmp   cl, [edx]
       jz    @Matched0
       cmp   cl, [edx+1]
       jz    @Matched1
       add   edx, 2
       cmp   edx, [esp+12]
       jb    @FindChar4
       cmp   edx, [esp+8]
       jb    @FindChar2
@NotFound:
       xor   eax, eax
       jmp   @Exit
@FindChar4:
       cmp   cl, [edx]
       jz    @Matched0
       cmp   cl, [edx+1]
       jz    @Matched1
       cmp   cl, [edx+2]
       jz    @Matched2
       cmp   cl, [edx+3]
       jz    @Matched3
       add   edx, 4
       cmp   edx, [esp+12]
       jb    @FindChar4
       cmp   edx, [esp+8]
       jb    @FindChar2
       xor   eax, eax
       jmp   @Exit

@FindString:
       sub   esi, 2
       mov   [esp+12], esi
@FindString2:
       cmp   cl, [edx]
       jz    @Test0
@NotMatched0:
       cmp   cl, [edx+1]
       jz    @Test1
@NotMatched1:
       add   edx, 2
       cmp   edx, [esp+12]
       jb    @FindString4
       cmp   edx, [esp+8]
       jb    @FindString2
       xor   eax, eax
       jmp   @Exit

@FindString4:
       cmp   cl, [edx]
       jz    @Test0
       cmp   cl, [edx+1]
       jz    @Test1
       cmp   cl, [edx+2]
       jz    @Test2
       cmp   cl, [edx+3]
       jz    @Test3
       add   edx, 4
       cmp   edx, [esp+12]
       jb    @FindString4
       cmp   edx, [esp+8]
       jb    @FindString2
       xor   eax, eax
       jmp   @Exit

@Test3:
       add   edx,2
@Test1:
       mov   esi, [esp]
@Loop1:
       movzx ebx, word ptr [esi+eax]
       cmp   bx, word ptr [esi+edx+1]
       jnz   @NotMatched1
       add   esi, 2
       jl    @Loop1
@Matched1:
       add   edx, 2
       xor   eax, eax
       cmp   edx, [esp+8]
       ja    @Exit1
@RetCode1:
       mov   eax, edx
       sub   eax, [esp+4]
@Exit1:
       add   esp, 16
       pop   esi
       pop   ebx
       ret
@Matched3:
       add   edx, 4
       xor   eax, eax
       cmp   edx, [esp+8]
       jbe   @RetCode1
       jmp   @Exit1

@Matched2:
       add   edx, 3
       jmp   @RetCode0
@Test2:
       add   edx,2
@Test0:
       mov   esi, [esp]
@Loop0:
       movzx ebx, word ptr [esi+eax]
       cmp   bx, word ptr [esi+edx]
       jnz   @NotMatched0
       add   esi, 2
       jl    @Loop0
@Matched0:
       inc   edx
@RetCode0:
       mov   eax, edx
       sub   eax, [esp+4]
@Exit:
       add   esp, 16
       pop   esi
       pop   ebx
end;

//Author:            John O'Harrow
//Optimized for:     AMD Athlon 64, Opteron, FX
//Instructionset(s): IA32
//Original name:     PosJOH_SSE_3

function FastCodePosXP(const SubStr: AnsiString; const Str: AnsiString): Integer;
asm
  test      eax, eax
  jz        @@NotFoundExit   {Exit if SubStr = ''}
  test      edx, edx
  jz        @@NotFound       {Exit if Str = ''}
  mov       ecx, [edx-4]     {Length(Str)}
  cmp       [eax-4], 1       {Length SubStr = 1?}
  je        @@SingleChar     {Yes - Exit via CharPos}
  jl        @@NotFound       {Exit if Length(SubStr) < 1}
  sub       ecx, [eax-4]     {Subtract Length(SubStr), -ve handled by CharPos}
  push      esi              {Save Registers}
  push      edi
  push      ebx
  push      ebp
  push      edx              {Save Start Address of Str}
  mov       ebx, [eax]       {BL = 1st Char of SubStr}
  mov       esi, eax         {Start Address of SubStr}
  lea       edi, [ecx+1]     {Initial Remainder Count}
@@StrLoop:
  mov       eax, ebx         {AL  = 1st char of SubStr}
  mov       ecx, edi         {Remaining Length}
  mov       ebp, edx         {Save Start Position}
  call      @@CharPos        {Search for 1st Character}
  jz        @@StrExit        {Exit with Zero Result if 1st Char Not Found}
  mov       ecx, [esi-4]     {Length SubStr}
  lea       edx, [ebp+eax]   {Update Start Position}
  sub       ecx, 1           {Remaining Characters to Compare}
  sub       edi, eax         {Update Remaining Length for Next Loop}
@@StrCheck:
  mov       ax, [edx+ecx-2]  {Compare Next 2 Chars of SubStr and Str}
  cmp       ax, [esi+ecx-1]
  jne       @@StrLoop        {Different - Return to First Character Search}
  sub       ecx, 2
  jg        @@StrCheck       {Check each Remaining Character}
  sub       edx, [esp]
  mov       eax, edx
@@StrExit:
  pop       edx              {Restore Registers}
  pop       ebp
  pop       ebx
  pop       edi
  pop       esi
  ret
@@NotFound:
  xor       eax, eax         {Return 0}
@@NotFoundExit:
  ret
@@SingleChar:
  mov       al, [eax]        {Search Character}
{Return Position of Character AL within a String of Length ECX starting}
{at Address EDX.  If Found, Return Index in EAX and Clear Zero Flag,   }
{otherwise Return 0 in EAX and Set Zero Flag.  Changes EAX, ECX and EDX}
@@CharPos:
  cmp       ecx, 8
  jg        @@NotSmall
@@Small:
  push      ecx
  or        ecx, ecx
  jle       @@SmallNotFound      {Exit if Length <= 0}
  cmp       al, [edx]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+1]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+2]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+3]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+4]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+5]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+6]
  jz        @@Found
  sub       ecx, 1
  jz        @@SmallNotFound
  cmp       al, [edx+7]
  jz        @@Found

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -