Mega Code Archive

 
Categories / Delphi / Strings
 

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;