Mega Code Archive
Delphi7 String Pattern Matching ASM function
Title: Delphi7 String Pattern Matching ASM function
Question: Use it when you want to compare strings using '*' or '?' operator
Answer:
Delphi7 String Pattern Matching ASM function
author: JunYu . Li ,a chinese , email: e271828@tom.com,165442523@qq.com
The Pos() in Delphi7 can not String Pattern Matching,but it publish its ASM source code.I now change the Pos() ASM code to String Pattern Matching ASM function posli().
The Posli() origin from pos(),I modify pos() to posli().
The posli() ASM function support one ? sign match one chinese word.The posli() only support ? and * sign,not support [] sign.
If substring have not * sign,the posli() return the first match index position ,if substring have * sign,the posli() return the last nearest * sign letter matching index position.
In conclusion,if posli() return higher than 0,it show match OK,otherwise match not OK.
The posli() parameter is pchar,it support length longer than 255.
Notice:The posli() have a bug,if * sign in substring just match * sign in the source string,the result may be wrong ,such as substring is "wwww*www",and source string is "aaaawwww*qwww" ,it ought to return bigger than 0,but posli() return 0.
Because the cmpsb ASM statement can not interrupt when * sign in substring just match * sign in the source string.Unless not using cmpsb ASM statement ,I now can not correct this bug.
function Posli( substr :pchar ; s : pchar ) : Integer;
var
dlen,sublen,esi0,edi0,starnum,starnum2,ifbacknum:integer;
asm
{ -EAX Pointer to substr }
{ EDX Pointer to string }
{ -EAX Position of substr in s or 0 }
PUSH EBX
PUSH ESI
PUSH EDI
MOV ESI,EAX { Point ESI to substr }
MOV EDI,EAX
MOV starnum,0
MOV starnum2,0
MOV dlen,0
MOV sublen,0
XOR ECX,ECX
MOV CL,[EDI]
INC EDI
////////////////////////
XOR ECX,ECX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
MOV sublen,ECX
//SUB sublen,2
/////////////////////////
MOV EDI,ESI
MOV AL,'*'
@@start0:
REPNE SCASB
JNE @@start
ADD starnum,1
JMP @@start0
//////////////////////////////
@@start:
///////////////////////////////
MOV EDI,EDX
INC EDI
XOR ECX,ECX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
MOV dlen,ECX
//SUB dlen,1
/////////////////////////////////////////
MOV EDI,EDX { Point EDI to s }
MOV esi0,ESI
MOV edi0,EDI
XOR ECX,ECX { ECX = Length(s) }
MOV CL,[EDI]
MOV ECX, dlen
PUSH EDI { remember s position to calculate index }
//INC EDI { Point EDI to first char of s }
XOR EDX,EDX { EDX = Length(substr) }
MOV DL,[ESI]
//INC ESI { Point ESI to first char of substr }
MOV EDX, sublen
CMP EDX,0 { EDX = Length(substr) - 1 }
JS @@fail { 0 ? return 0 }
MOV AL,[ESI] { AL = first char of substr }
//INC ESI { Point ESI to 2'nd char of substr }
DEC EDX
SUB ECX,EDX { #positions in s to look at }
{ = Length(s) - Length(substr) + 1 }
ADD ECX,starnum
JLE @@fail
PUSH ESI { save outer loop substr pointer }
PUSH EDI { save outer loop s pointer }
MOV ECX,sublen
ADD EDI,1
JMP @@star
@@loop:
REPNE SCASB
JNE @@fail
MOV EBX,ECX { save outer loop counter }
PUSH ESI { save outer loop substr pointer }
PUSH EDI { save outer loop s pointer }
MOV ECX,EDX
@@loopwww:
// MOV AL,[ESI]
// MOV AL,[ESI-1]
//MOV AL,[ESI-2]
REPE CMPSB
//PUSH ESI
JE @@found
//INC EDI
///////////////
//MOV AL,[ESI]
//MOV AL,[ESI-1]
//MOV AL,[EDI-1]
//CMP AL,[ESI-1]
//JE @@found
CMP ECX,0
JE @@iffound1
{MOV AL,[ESI]
CMP AL,$12
JE @@found
CMP AL,$0
JE @@found
CMP AL,$FF
JE @@found}
/////////////////
@@iffound2:
//PUSH EAX
MOV AL,[ESI]
SUB ESI,1
MOV AL,[ESI]
INC ESI
//INC ESI
CMP AL,'?'
//POP ESI
JE @@what
CMP AL,'*'
JE @@star
//MOV AL,[ESI]
//CMP AL,$12
//JE @@fail2
//CMP AL,$0
//JE @@fail2
//POP EAX
MOV AL,[EDI]
CMP AL,$12
JE @@fail2
CMP AL,$0
JE @@fail2
////////////////
POP EDI { restore outer loop s pointer }
POP ESI { restore outer loop substr pointer }
MOV ECX,EBX { restore outer loop counter }
JMP @@loopOK
@@what:
MOV EAX,0
MOV EAX,EDI
SUB EAX,dlen
CMP EAX,edi0
JG @@fail2
///////
MOV AL,[ESI]
CMP AL,$12
//POP EAX
JE @@found
CMP AL,$0
JE @@found
CMP ECX,0
JE @@found
/////////////////////
MOV AL,[EDI]
CMP AL,$80
JNB @@chinese
@@whatchinese:
MOV AL,[ESI]
////////////////////////
JMP @@loopwww
@@chinese:
ADD EDI,1
JMP @@whatchinese
@@star:
ADD starnum2,1
SUB EDI,1
MOV AL,[ESI]
CMP AL,$12
//POP EAX
JE @@found
CMP AL,$0
JE @@found
// POP EAX
// POP EAX
@@www:
CMP ECX,0
JE @@found
MOV EAX,0
MOV EAX,EDI
SUB EAX,dlen
CMP EAX,edi0
JG @@fail2
////////////////////
MOV AL,[ESI]
ADD ESI,1
SUB ECX,1
//MOV AL,[ESI]
//INC ESI
CMP AL,'?'
//POP ESI
JE @@qq
CMP AL,'*'
JE @@www
CMP AL,$12
//POP EAX
JE @@found
CMP AL,$0
JE @@found
//POP EAX
SUB ESI,1
ADD ECX,1
POP EAX
POP EAX
/////////////////////////
//////////////////////////////
@@loopOK: MOV AL,[ESI] { AL = first char of substr }
// INC ESI { Point ESI to 2'nd char of substr }
// SUB ECX,EDX { #positions in s to look at }
{ = Length(s) - Length(substr) + 1 }
// JLE @@fail
//MOV ECX,dlen-(EDI-edi0)-(sublen-(ESI-esi0))+1+starnum//-starnum2
MOV ECX,dlen
SUB ECX,EDI
ADD ECX,edi0
SUB ECX,sublen
ADD ECX,ESI //esi?1?ESI0?0??????
SUB ECX,esi0
//ADD ECX,2 //STRING
ADD ECX,1 //PCHAR
ADD ECX,starnum
//SUB ECX,starnum2
CMP ECX,0
JLE @@fail
REPNE SCASB
JNE @@fail
//MOV EBX,ECX { save outer loop counter }
///////////////////////////////////////////////////////
PUSH EAX
PUSH EDI
SUB EDI,1
MOV AL,[EDI]
CMP AL,$80
POP EDI
POP EAX
JNB @@IFBACK
///////////////////////////////////////////////////////
@@IFLEAD:
//ADD ESI,1
MOV ECX,sublen
SUB ECX,ESI
ADD ECX,esi0
SUB ECX,1 //PCHAR?
//SUB ECX,1
PUSH ESI { save outer loop substr pointer }
INC ESI
PUSH EDI { save outer loop s pointer }
//PUSH EDX
MOV ECX,ECX
CMP ECX,0
JE @@found
//POP EDX
JMP @@loopwww
@@IFBACK:
PUSH EDI
PUSH EAX
MOV ifbacknum,0
SUB EDI,1
@@ifback2:
ADD EDI,1
CMP EDI,edi0
JE @@ifback1
MOV AL,[EDI]
CMP AL,$80
JB @@ifback1
NOT ifbacknum
JMP @@ifback2
@@ifback3:
POP EAX
POP EDI
JMP @@IFLEAD
@@ifback1:
CMP ifbacknum,0
JNE @@ifback3
POP EAX
POP EDI
ADD EDI,1
JMP @@loopOK
@@qq:
POP EAX
ADD EDI,1
///////////////
//PUSH EAX
MOV AL,[EDI]
CMP AL,$80
JNB @@chinese0
@@whatchinese0:
//POP EAX
////////////////////////
PUSH EDI
JMP @@www
@@qqq:
ADD EDI,1
///////////////
PUSH EAX
MOV AL,[EDI]
CMP AL,$80
JNB @@chinese0
POP EAX
////////////////////////
PUSH EDI
JMP @@www
@@chinese0:
ADD EDI,1
JMP @@whatchinese0
@@fail2:
POP EDX
POP EDX
@@fail:
POP EDX { get rid of saved s pointer }
XOR EAX,EAX
JMP @@exit
@@iffound1:
MOV AL,[ESI]
MOV AL,[ESI-1]
MOV AL,[EDI-1]
CMP AL,[ESI-1]
JE @@found
JMP @@iffound2
@@found:
POP EDI { restore outer loop s pointer }
POP ESI { restore outer loop substr pointer }
POP EDX { restore pointer to first char of s }
MOV EAX,EDI { EDI points of char after match }
SUB EAX,EDX { the difference is the correct index }
@@exit:
POP EDI
POP ESI
POP EBX
end;