用MASM32来DIY一个判断字符串1是否为字符串2的子串的函数(应用repe cmpsb指令,区分大小写)

  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 ebxeax

    mov esi, lpsz1
    ;串1长度
    invoke lstrlen, esi
   
    ;串2长度 < 串1长度?
    cmp ebxeax ;eax=串1长度

    ;串2长度 < 串1长度,返回-1
    jl  @isSubStr1NoResult

    mov ecxeax    ;串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  ebxecx
    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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫郢剑侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值