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