Windows貌似没有提供判断字符串1是否为字符串2的子串的 API函数,我们可以DIY一个。
实现的方法很多,我们先应用ASM特有的repe cmpsb指令来实现。
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文 件 名:isSubStr.asm (控制台程序)
; 功 能:判断字符串1是否为字符串2的子串(应用repe cmpsb指令,区分大小写)
; 开发环境:Win xp pro sp3 + MASM32 v11
; 作 者:PurpleEndurer, 2014-10-04,广西河池
; 首 发:http://blog.csdn.net/purpleendurer
; 代码下载:http://download.csdn.net/detail/purpleendurer/8002767(源代码+exe)
; 16位版本:http://blog.csdn.net/purpleendurer/article/details/232936
; 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
isSubStr1 proto :dword, :dword
isSubStr2 proto :dword, :dword
isSubStri 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_szFmt db "%s %s %d", 0dh, 0ah, 0
g_buf20 db 20 dup(0)
;ssssssssssssssssssssssss
.CODE
;ssssssssssssssssssssssss
start:
invoke StdOut, ADDR g_szAppInfo
invoke isSubStr1, 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 isSubStr1, 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 isSubStr1, 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 isSubStr1, 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 isSubStr1, 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 ExitProcess, 0
;======================================================
isSubStr1 proc lpsz1:dword, lpsz2:dword
; 功能:判断字符串1是否为字符串2的子串(区分大小写)
; 入口:lpsz1:串1地址 lpsz2:串2地址
; 出口:eax=-1,不是子串
; eax>=0,子串首次出现位置
;======================================================
mov edi, lpsz2
;串2长度
invoke lstrlen, edi
mov ebx, eax
mov esi, lpsz1
;串1长度
invoke lstrlen, esi
;串2长度 < 串1长度?
cmp ebx, eax ;eax=串1长度
;串2长度 < 串1长度,返回-1
jl @isSubStr1NoResult
mov ecx, eax ;串1长度
cld
@isSubStr1LoopCmp:
push ecx ;串1长度
push esi ;串1首址
push edi
repe cmpsb
jne @F ;发现不匹配的,继续比较
jecxz @isSubStr1YesResult ;完全匹配
@@:
pop edi ;恢复串2本次比较的首址
inc edi ;使串2首址加1,指向下一个字符, 以便下次比较
dec ebx ;串2长度减1
pop esi ;恢复串1首址
pop ecx ;恢复串1长度
cmp ebx, ecx
jge @isSubStr1LoopCmp ;串2长度>=串1长度, 继续比较
@isSubStr1NoResult:
mov eax, -1
jmp @isSubStr1Ret
@isSubStr1YesResult:
pop eax ;弹出先前压入的edi, 即本次比较时的串2的首址
pop esi ;弹出esi, 无用
pop ecx ;弹出串1长度
sub eax, lpsz2 ;计算串1在串2中的位置
@isSubStr1Ret:
ret
isSubStr1 endp
END start