16,749
社区成员
发帖
与我相关
我的任务
分享
function IsSameText(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX //Str1
MOV EDI,EDX //Str2
MOV EBX,ECX //Len
XOR EAX,EAX
OR ECX,ECX
JE @@T
REPNE SCASB //扫描ESI/EDI指针指向的字符,当不相等的时候结束,否则扣减ECX计数,直到计数为0结束
SUB EBX,ECX
MOV ECX,EBX
MOV EDI,EDX
XOR EDX,EDX
@@1: REPE CMPSB
JE @@T
MOV AL,[ESI-1] //AL = Str1[Index]
CMP AL,'a'
JB @@2
CMP AL,'z'
JA @@2
SUB AL,20H //To Upper
@@2: MOV DL,[EDI-1] //DL = Str2[Index]
CMP DL,'a'
JB @@3
CMP DL,'z'
JA @@3
SUB DL,20H //To Upper
@@3: SUB AL,DL
JE @@1 //AL - DL = 0? NextChar:End (return False)
@@F: xor EAX,EAX //False,EAX return 0
jmp @@E
@@T: mov EAX,1 //True,EAX return 1
@@E: POP EBX
POP ESI
POP EDI
end;
function IsSameText(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX //Str1
MOV EDI,EDX //Str2
MOV EBX,ECX //Len
XOR EAX,EAX
OR ECX,ECX
JE @@T
REPNE SCASB //扫描ESI/EDI指针指向的字符,当不相等的时候结束,否则扣减ECX计数,直到计数为0结束
SUB EBX,ECX
MOV ECX,EBX
MOV EDI,EDX
XOR EDX,EDX
LEA EBX,CS:[OFFSET @LOWER]
@@1: REPE CMPSB
JE @@T
MOV AL,[ESI-1] //AL = Str1[Index]
MOV AL,[EBX + EAX] //AL = Lower[Ord(AL)]
@@2: MOV DL,[EDI-1] //DL = Str2[Index]
MOV DL,[EBX + EDX] //DL = Lower[Ord(DL)]
@@3: SUB AL,DL //AL = AL - DL
JE @@1 //AL = 0? NextChar: End (return false)
@@F: xor EAX,EAX
jmp @@E
@@T: mov EAX,1
@@E: POP EBX
POP ESI
POP EDI
RET
@LOWER: DB 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h, 008h, 009h, 00ah, 00bh, 00ch, 00dh, 00eh, 00fh
DB 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h, 018h, 019h, 01ah, 01bh, 01ch, 01dh, 01eh, 01fh
DB 020h, 021h, 022h, 023h, 024h, 025h, 026h, 027h, 028h, 029h, 02ah, 02bh, 02ch, 02dh, 02eh, 02fh
DB 030h, 031h, 032h, 033h, 034h, 035h, 036h, 037h, 038h, 039h, 03ah, 03bh, 03ch, 03dh, 03eh, 03fh
DB 040h
//大写字母
//---------------------
(*DB 041h, 042h, 043h, 044h, 045h, 046h, 047h, 048h, 049h, 04ah, 04bh, 04ch, 04dh, 04eh, 04fh
DB 050h, 051h, 052h, 053h, 054h, 055h, 056h, 057h, 058h, 059h, 05ah*)
//=====================
//小写字母
//---------------------
DB 061h, 062h, 063h, 064h, 065h, 066h, 067h, 068h, 069h, 06ah, 06bh, 06ch, 06dh, 06eh, 06fh
DB 070h, 071h, 072h, 073h, 074h, 075h, 076h, 077h, 078h, 079h, 07ah
//=====================
DB 05bh, 05ch, 05dh, 05eh, 05fh
DB 060h
//---------------------
//小写字母
DB 061h, 062h, 063h, 064h, 065h, 066h, 067h, 068h, 069h, 06ah, 06bh, 06ch, 06dh, 06eh, 06fh
DB 070h, 071h, 072h, 073h, 074h, 075h, 076h, 077h, 078h, 079h, 07ah
//======================
DB 07bh, 07ch, 07dh, 07eh, 07fh
DB 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h, 088h, 089h, 08ah, 08bh, 08ch, 08dh, 08eh, 08fh
DB 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h, 098h, 099h, 09ah, 09bh, 09ch, 09dh, 09eh, 09fh
DB 0a0h, 0a1h, 0a2h, 0a3h, 0a4h, 0a5h, 0a6h, 0a7h, 0a8h, 0a9h, 0aah, 0abh, 0ach, 0adh, 0aeh, 0afh
DB 0b0h, 0b1h, 0b2h, 0b3h, 0b4h, 0b5h, 0b6h, 0b7h, 0b8h, 0b9h, 0bah, 0bbh, 0bch, 0bdh, 0beh, 0bfh
DB 0c0h, 0c1h, 0c2h, 0c3h, 0c4h, 0c5h, 0c6h, 0c7h, 0c8h, 0c9h, 0cah, 0cbh, 0cch, 0cdh, 0ceh, 0cfh
DB 0d0h, 0d1h, 0d2h, 0d3h, 0d4h, 0d5h, 0d6h, 0d7h, 0d8h, 0d9h, 0dah, 0dbh, 0dch, 0ddh, 0deh, 0dfh
DB 0e0h, 0e1h, 0e2h, 0e3h, 0e4h, 0e5h, 0e6h, 0e7h, 0e8h, 0e9h, 0eah, 0ebh, 0ech, 0edh, 0eeh, 0efh
DB 0f0h, 0f1h, 0f2h, 0f3h, 0f4h, 0f5h, 0f6h, 0f7h, 0f8h, 0f9h, 0fah, 0fbh, 0fch, 0fdh, 0feh, 0ffh
end;
function CompareText(const S1, S2: string): Integer; assembler;
asm
PUSH ESI
PUSH EDI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
OR EAX,EAX
JE @@0
MOV EAX,[EAX-4]
@@0: OR EDX,EDX
JE @@1
MOV EDX,[EDX-4]
@@1: MOV ECX,EAX
CMP ECX,EDX
JBE @@2
MOV ECX,EDX
@@2: CMP ECX,ECX
@@3: REPE CMPSB
JE @@6
MOV BL,BYTE PTR [ESI-1]
CMP BL,'a'
JB @@4
CMP BL,'z'
JA @@4
SUB BL,20H
@@4: MOV BH,BYTE PTR [EDI-1]
CMP BH,'a'
JB @@5
CMP BH,'z'
JA @@5
SUB BH,20H
@@5: CMP BL,BH
JE @@3
MOVZX EAX,BL
MOVZX EDX,BH
@@6: SUB EAX,EDX
POP EBX
POP EDI
POP ESI
end;
其实我是来接分的。[code=Delphi(Pascal)](*新版Delphi自带的函数*)
function CompareText(const S1, S2: string): Integer;
asm
TEST EAX, EAX
JNZ @@CheckS2
TEST EDX, EDX
JZ @@Ret
MOV EAX, [EDX-4]
NEG EAX
@@Ret:
RET
@@CheckS2:
TEST EDX, EDX
JNZ @@Compare
MOV EAX, [EAX-4]
RET
@@Compare:
PUSH EBX
PUSH EBP
PUSH ESI
MOV EBP, [EAX-4] // length(S1)
MOV EBX, [EDX-4] // length(S2)
SUB EBP, EBX // Result if All Compared Characters Match
SBB ECX, ECX
AND ECX, EBP
ADD ECX, EBX // min(length(S1),length(S2)) = Compare Length
LEA ESI, [EAX+ECX] // Last Compare Position in S1
ADD EDX, ECX // Last Compare Position in S2
NEG ECX
JZ @@SetResult // Exit if Smallest Length = 0
@@Loop: // Load Next 2 Chars from S1 and S2
// May Include Null Terminator}
MOVZX EAX, WORD PTR [ESI+ECX]
MOVZX EBX, WORD PTR [EDX+ECX]
CMP EAX, EBX
JE @@Next // Next 2 Chars Match
CMP AL, BL
JE @@SecondPair // First Char Matches
MOV AH, 0
MOV BH, 0
CMP AL, 'a'
JL @@UC1
CMP AL, 'z'
JG @@UC1
SUB EAX, 'a'-'A'
@@UC1:
CMP BL, 'a'
JL @@UC2
CMP BL, 'z'
JG @@UC2
SUB EBX, 'a'-'A'
@@UC2:
SUB EAX, EBX // Compare Both Uppercase Chars
JNE @@Done // Exit with Result in EAX if Not Equal
MOVZX EAX, WORD PTR [ESI+ECX] // Reload Same 2 Chars from S1
MOVZX EBX, WORD PTR [EDX+ECX] // Reload Same 2 Chars from S2
CMP AH, BH
JE @@Next // Second Char Matches
@@SecondPair:
SHR EAX, 8
SHR EBX, 8
CMP AL, 'a'
JL @@UC3
CMP AL, 'z'
JG @@UC3
SUB EAX, 'a'-'A'
@@UC3:
CMP BL, 'a'
JL @@UC4
CMP BL, 'z'
JG @@UC4
SUB EBX, 'a'-'A'
@@UC4:
SUB EAX, EBX // Compare Both Uppercase Chars
JNE @@Done // Exit with Result in EAX if Not Equal
@@Next:
ADD ECX, 2
JL @@Loop // Loop until All required Chars Compared
@@SetResult:
MOV EAX, EBP // All Matched, Set Result from Lengths
@@Done:
POP ESI
POP EBP
POP EBX
end;
function SameText(const S1, S2: string): Boolean; assembler;
asm
CMP EAX,EDX
JZ @1
OR EAX,EAX
JZ @2
OR EDX,EDX
JZ @3
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JNE @3
CALL CompareText
TEST EAX,EAX
JNZ @3
@1: MOV AL,1
@2: RET
@3: XOR EAX,EAX
end;
[/code]function IsSameText(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;
asm
TEST EAX, EAX
JNZ @@CheckS2
...
function IsSameText1(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;
asm
PUSH ESI
PUSH EBX
CMP EAX,EDX //Compare Str1,Str2
JE @@T //Str1 == Str2 ? return True
TEST EAX,EDX //(Str1 & str2)
JZ @@F //(Str1 & str2) == NULL? return False
Lea ESI,[EAX + ECX] //ESI = Str1 + Len
ADD EDX,ECX //EDX = Str2 + Len
XOR EBX,EBX //EBX = 0
XOR EAX,EAX //EAX = 0
NEG ECX //ECX *= -1
JZ @@T //ECX == 0? return True
@@DWORD:
CMP ECX,-4 //Compare ECX,-4
JG @@Word //ECX > -4 ? Next Two Bytes
MOV EAX,DWORD PTR [ESI+ECX] //Load Four Bytes from Str1
MOV EBX,DWORD PTR [EDX+ECX] //Load Four Bytes from Str2
CMP EAX,EBX
JE @@NextDword
CMP AX,BX
JE @@HiWord
SUB AL,BL
JZ @@NextByteOfLODWORD
JC @@UC41
CMP AL,20h
JNZ @@F
CMP BL,'A'
JL @@F
CMP BL,'Z'
JG @@F
JMP @@NextByteOfLODWORD
@@UC41:
CMP AL,-20h
JNZ @@F
CMP BL,'a'
JL @@F
CMP BL,'z'
JG @@F
@@NextByteOfLODWORD:
SUB AH,BH
JZ @@HiWord
JC @@UC42
CMP AH,20h
JNZ @@F
CMP BH,'A'
JL @@F
CMP BH,'Z'
JG @@F
JMP @@HiWord
@@UC42:
CMP AH,-20h
JNZ @@F
CMP BH,'a'
JL @@F
CMP BH,'z'
JG @@F
@@HiWord:
SHR EAX,16
SHR EBX,16
CMP AX,BX
JE @@NextDword
SUB AL,BL
JZ @@NextByteOfHIDWORD
JC @@UC43
CMP AL,20h
JNZ @@F
CMP BL,'A'
JL @@F
CMP BL,'Z'
JG @@F
JMP @@NextByteOfHIDWORD
@@UC43:
CMP AL,-20h
JNZ @@F
CMP BL,'a'
JL @@F
CMP BL,'z'
JG @@F
@@NextByteOfHIDWORD:
SUB AH,BH
JZ @@NextDword
JC @@UC44
CMP AH,20h
JNZ @@F
CMP BH,'A'
JL @@F
CMP BH,'Z'
JG @@F
JMP @@NextDword
@@UC44:
CMP AH,-20h
JNZ @@F
CMP BH,'a'
JL @@F
CMP BH,'z'
JG @@F
@@NextDword:
Add ECX,4
JL @@DWORD
@@Word:
CMP ECX,-2
JG @@Byte
MOV BX,WORD PTR [EDX+ECX]
MOV AX,WORD PTR [ESI+ECX]
CMP AX,BX
JE @@NextWord
SUB AL,BL
JZ @@NextByteOfWORD
JC @@UC21
CMP AL,20h
JNZ @@F
CMP BL,'A'
JL @@F
CMP BL,'Z'
JG @@F
JMP @@NextByteOfWORD
@@UC21:
CMP AL,-20h
JNZ @@F
CMP BL,'a'
JL @@F
CMP BL,'z'
JG @@F
@@NextByteOfWORD:
SUB AH,BH
JZ @@NextWord
JC @@UC22
CMP AH,20h
JNZ @@F
CMP BH,'A'
JL @@F
CMP BH,'Z'
JG @@F
JMP @@NextWord
@@UC22:
CMP AH,-20h
JNZ @@F
CMP BH,'a'
JL @@F
CMP BH,'z'
JG @@F
@@NextWord:
Add ECX,2
//JL @@WORD
@@Byte:
CMP ECX,-1
JG @@T
MOV BL,BYTE PTR [EDX+ECX]
MOV AL,BYTE PTR [ESI+ECX]
SUB AL,BL
JZ @@NextByte
JC @@UC10
CMP AL,20h
JNZ @@F
CMP BL,'A'
JL @@F
CMP BL,'Z'
JG @@F
JMP @@NextByte
@@UC10:
CMP AL,-20h
JNZ @@F
CMP BL,'a'
JL @@F
CMP BL,'z'
JG @@F
@@NextByte:
INC ECX
//JL @@Byte
@@T: mov EAX,1
jmp @@E
@@F: xor EAX,EAX
@@E:
POP EBX
POP ESI
end;
(*测试代码*)
var
Str1,Str2: String;
iLen,iCount: DWORD;
iStart0,iEnd0,
iStart1,iEnd1,
iStart2,iEnd2:DWORD;
Result0,
Result1,
Result2: Boolean;
I: Integer;
begin
{$OPTIMIZATION OFF} //这里只是用于做测试,为了达到测试效果,关闭编译器优化选项
Result0 := false;
Result1 := false;
Result2 := false;
iLen := 1024*1024*550; //550MB(视个人机器内存的情况进行调整)
iCount := 50; //次数(由于内存有限,就增加次数,以拉大结果之间的差距)
SetLength(Str1,iLen);
SetLength(Str2,iLen);
fillchar(PChar(Str1)^,ilen,$41); //$41,即ASCII 65,字符'A'
fillchar(PChar(Str2)^,ilen,$41); //$41,即ASCII 65,字符'A'
//随机将部分字符改为$61,即小写的'a'(ASCII 97)
for I := 0 to 1024*1024*5 - 1 do
begin
Randomize;
PChar(PChar(Str2)+Random(iLen))^ := chr($61);
end;
//第一个函数IsSameText的测试
iStart0 := GetTickCount;
for I := 0 to iCount - 1 do
Result0 := IsSameText(PChar(Str1),PChar(Str2),iLen);
iEnd0 := GetTickCount;
//第二个函数IsSameText1的测试
iStart1 := iEnd0;
for I := 0 to iCount - 1 do
Result1 := IsSameText1(PChar(Str1),PChar(Str2),iLen) ;
iEnd1 := GetTickCount;
//系统的SameText(CompareText)测试
iStart2 := iEnd1;
for I := 0 to iCount - 1 do
Result2 := SameText(Str1 , Str2);//这里可以使用 "CompareText(Str1, Str2) = 0 "代替
iEnd2 := GetTickCount;
ShowMessage(Format( ' IsSameText:%d,%s'#13#10+
'IsSameText1:%d,%s'#13#10+
' SameText:%d,%s',
[ iEnd0 - iStart0 (*时间消耗*), BoolToStr(Result0, true) (*结果*),
iEnd1 - iStart1, BoolToStr(Result1,true),
iEnd2 - iStart2, BoolToStr(Result2,true)
]));
end;