📄 fastcodepos.pas
字号:
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 + -