DELPHI7的通配符比較的匯編函數(shù)
DELPHI7中的POS()函數(shù)是不能用通配符的,但是有匯編代碼公開(kāi)的,于是我想能否把此匯編函數(shù)改編成可能用通配符,有此想法已有多年了,最近我重新研究這個(gè)問(wèn)題,發(fā)現(xiàn)是可行了,并做了出來(lái),由于時(shí)間倉(cāng)促,錯(cuò)誤在所難免,希望能發(fā)現(xiàn)此匯編函數(shù)有BUG者能反饋給我知,我就多謝大家了。下面是我修改DELPHI7中的POS()而成的POSLI()的匯編源碼,我試過(guò)可以通配符的,未知有無(wú)什么BUG,希望有人通知我BUG在何處。
此匯編函數(shù)支持?號(hào)只匹配一個(gè)中文。只支持?號(hào)和*號(hào),不支持[]號(hào)。例如:子串為"Edit*1*2*3?4*5",源串為"Edit111www222123國(guó)45qEdit222www333qq"時(shí)將返回最后一個(gè)*號(hào)之后第一個(gè)字符的匹配處INDEX。
如果子串沒(méi)有*號(hào),返回子串第一個(gè)字符的匹配INDEX,如果子串有*號(hào),返回最后一個(gè)最接近*號(hào)的字符的匹配INDEX值?傊,返回值大于0就表示匹配成功了。
此函數(shù)支持中文查找,如子串為"謝",源串為"中華",返回0,雖然中之后半字節(jié)和華之前半字節(jié)合成謝字,但我這匯編函數(shù)已做了處理了。
此匯編函數(shù)參數(shù)為PCHAR,可以傳多于255個(gè)字符的字串作參數(shù)也!
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
////////////////有可能源串短于子串也,因?號(hào)匹配中文也
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
JGE @@fail2
///////如果源串已結(jié)束則必NO //BUG
MOV AL,[ESI]
CMP AL,$12 //此當(dāng)結(jié)束
//POP EAX
JE @@found
CMP AL,$0
JE @@found
//push eax
//MOV AL,[ESI]
//CMP AL,$0 //此也當(dāng)結(jié)束,為經(jīng)驗(yàn),不知何解
//POP EAX
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
/////////
//XOR ECX,ECX
// MOV CL,[EDI]
// INC EDI { Point EDI to first char of s }
// PUSH EDI { remember s position to calculate index }
// XOR EDX,EDX { EDX = Length(substr) }
// MOV DL,[ESI]
// INC ESI { Point ESI to first char of substr }
// DEC EDX { EDX = Length(substr) - 1 }
// JS @@fail { < 0 ? return 0 }
// XOR EAX,EAX
//////////////////////////
////////////////////
//PUSH 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