Windows貌似没有提供判断字符串1是否为字符串2的子串的 API函数,我们可以DIY一个。

先应用ASM特有的repe cmpsb指令来实现,详见:


来实现。从串2头部开始用lstrcpyn()复制与串1相同长度的字符串,再用lstrcmp()来与串1进行比较,直到发现匹配或者串2剩余长度>串1长度。

 

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


; 文 件 名:isSubStr.asm (控制台程序)


; 功    能: 判断字符串1是否为字符串2的字串(区分大小写)


; 开发环境:Win xp pro sp3 + MASM32 v11


; 作    者:PurpleEndurer, 2014-10-04,广西河池



; log


; --------------------------------------------------


; 2014-10-04 开始编写


;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<



.586


.MODEL 

FLAT, STDCALL


OPTION 

CASEMAP: NONE



INCLUDE \masm32\

include\windows.inc



INCLUDE \masm32\

include\kernel32.inc


INCLUDELIB \masm32\

lib\kernel32.lib



INCLUDE \masm32\

include\ole32.inc


INCLUDELIB \masm32\

lib\ole32.lib



INCLUDE \masm32\

include\user32.inc


INCLUDELIB \masm32\

lib\user32.lib



INCLUDE \masm32\

include\msvcrt.inc


INCLUDELIB \masm32\

lib\msvcrt.lib



INCLUDE \masm32\macros\MACROS.ASM



INCLUDE \masm32\

include\masm32.inc


INCLUDELIB \masm32\

lib\masm32.lib




isSubStr2 

proto : dword, : dword



;ssssssssssssssssssssssss


;.const


;ssssssssssssssssssssssss



g_debug 

equ 0



;ssssssssssssssssssssssss


.DATA


;ssssssssssssssssssssssss



    g_szAppInfo 

db  "文 件 名:isSubstr.asm", 0dh ,0ah


                

db  "功  能:判断字符串1是否为字符串2的字串", 0dh ,0ah


            

db  "作  者:PurpleEndurer, 2014-10-04,广西河池", 0dh ,0ah


            

db  "开发环境:Win xp Pro sp3 + MASM32 v11", 0dh ,0ah, 0




    g_sz1 

db  "bc", 0


    g_sz2 

db  "abcde", 0


    g_sz3 

db  "ac", 0


    g_sz4 

db  "cDe",0


    g_sz5 

db  "Bcd",0


    g_sz6 

db  "abcdef123",0



    


    g_szFmt 

db  "%s %s %d", 0dh, 0ah, 0


    g_buf20 

db 20 dup(0)



;ssssssssssssssssssssssss


.CODE


;ssssssssssssssssssssssss


start:



    

invoke StdOut,  ADDR g_szAppInfo


    

invoke isSubStr2,  offset g_sz1,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz1,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20



    

invoke isSubStr2,  offset g_sz2,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz2,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20



    

invoke isSubStr2,  offset g_sz3,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz3,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20



    

invoke isSubStr2,  offset g_sz4,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz4,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20



    

invoke isSubStr2,  offset g_sz5,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz5,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20


    



    

invoke isSubStr2,  offset g_sz6,  offset g_sz2


    

invoke wsprintf,  offset g_buf20,  offset g_szFmt,  offset g_sz6,  offset g_sz2,  eax


    

invoke StdOut,  offset g_buf20


    

invoke ExitProcess, 0





;======================================================


isSubStr2 

proc lpsz1: dword, lpsz2: dword


; 功能:判断字符串1是否为字符串2的字串(区分大小写)


; 入口:lpsz1:串1地址 lpsz2:串2地址


; 出口:eax=-1,不是子串


;       eax>=0,子串首次出现位置


;======================================================


    

local buf256[256]:  byte


    

local dwCopyBytes:  dword



    

mov  edi, lpsz2


    

;串2长度


    

invoke lstrlen,  edi


    

mov  ebx,  eax


    


    

mov  esi, lpsz1


    

;串1长度


    

invoke lstrlen,  esi



    

;串2长度 < 串1长度?


    

cmp  ebx,  eax  ;eax=length of lpsz1



    

;串2长度 < 串1长度,返回-1


    

;mov eax, -1


    

jl  @isSubStr2NoResult



    

mov  ecx,  eax


    

inc  eax


    

mov dwCopyBytes,  eax


@isSubStr2LoopCmp:


    

push  ecx     ;串1长度


    

push  ebx     ;串2长度


    

push  edi


    

invoke lstrcpyn,  addr buf256,  edi, dwCopyBytes


    

invoke lstrcmp,  addr buf256, lpsz1


    

test  eax,  eax


    

jz @isSubStr2YesResult  ;完全匹配



    

pop   edi    ;恢复串2本次比较的首址


    

inc   edi    ;使串2首址加1,指向下一个字符, 以便下次比较


    

pop   ebx    ;恢复串2长度


    

dec   ebx    ;串2长度减1


    

pop   ecx     ;串1长度


    

cmp   ebx,  ecx


    

jge  @isSubStr2LoopCmp  ;串2长度>=串1长度, 继续比较


@isSubStr2NoResult:


    

mov   eax, -1


    

jmp  @isSubStr2Ret   


@isSubStr2YesResult:


    

pop   eax    ;弹出先前压入的edi, 即本次比较时的串2的首址


    

pop   esi    ;弹出esi, 无用


    

pop   ecx    ;弹出串1长度, 无用


    

sub   eax, lpsz2   ;计算串1在串2中的位置



@isSubStr2Ret:


    

ret


isSubStr2 

endp




END start isSubStr1 

endp



END