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