用MASM32写了一个查找替换的字串函数!ANSI及UNICODE两个版本

最近在编写软件时老是为没有一个齐全的优良的框架而烦恼。所以,在一而再,再而三的打击、遍体鳞伤之下,在下才祭出屠龙宝刀MASM v8.0,于深山老林中,月圆之夜,潜修武林密决!终于,经过一些高级语言的RTL的冲撞及抛砖引玉之下,在下悟出了一些所谓的盖世神功武林密决——Utils函数……

话音锋回路转,我们将话题扭转到至今,刚才在整理ANSI及UNICODE的字符串函数时,感觉MStrRepA及MStrRepW应该对同道中人或许还能取到旷世之神效,所以就贴了上来。由于在下才舒学浅,还得请前辈大侠们多多关照和包函,如果还能指点小的一二,吾将不胜感激!

原理我想大家都知道了,那么我就不废话了,以下是代码。希望对有用得着的同道中人有所帮助,或是取到抛砖引玉之功效!

 

1、UNICODE Version:

 

MStrRepW proc uses esi edi ebx pszExpression:DWORD, pszFind:DWORD, pszReplaceWith:DWORD, nStart:DWORD, nCount:DWORD

    local szBuf[1024]:word

    ; check the pszExpression string whether empty
    mov     eax, DWORD ptr [pszExpression]
    or      eax, eax
    jz      @Error
   
    ; check the pszFind string whether empty
    mov     edx, DWORD ptr [pszFind]
    or      edx, edx
    jz      @Error
   
    cld
   
    ; add nStart
    mov     ebx, eax                    ; first addr of pszExpression
    mov     eax, DWORD PTR [nStart]
    inc     eax
    je      @IsZeroSide
    dec     eax
    lea     ebx, [ebx+eax*2]            ; start pos from pszExpression
  @IsZeroSide:
 
    ; search length of pszFind
    mov     edi, edx                    ; search pszFind
    xor     ecx, ecx
    dec     ecx
    xor     eax, eax
    repne   scasw
    not     ecx
    dec     ecx         ; length of pszSrc
    jz      @Error      ; if has not any chars then go to final
   
    mov     esi, ecx    ; backup the length of pszFind

;    ; set nCount
;    mov     eax, DWORD PTR [nCount]
;    inc     eax
;    je      @IsWhole
;    ;dec     eax
;    mov     ecx, eax            ; start pos from pszExpression
;    jmp     @NoSearchDstNull
;  @IsWhole:
;   
;    ; check the length of pszExpression string whether less than length of pszFind string
;    mov     edi, ebx    ; pszExpression
;    xor     ecx, ecx
;    dec     ecx
;    xor     eax, eax
;    repne   scasw
;    not     ecx
;    mov     eax, ecx
;  @NoSearchDstNull:
;    cmp     eax, esi
;    jbe     @Error

    ; check the length of pszExpression string whether less than length of pszFind string
    mov     edi, ebx    ; pszExpression
    xor     ecx, ecx
    dec     ecx
    xor     eax, eax
    repne   scasw
    not     ecx
    mov     eax, DWORD PTR [nCount]
    inc     eax
    je      @IsWhole
    cmp     eax, ecx
    ja      @IsWhole
    mov     ecx, eax
  @IsWhole:
    mov     eax, ecx
    cmp     eax, esi
    jbe     @Error
   
    mov     edi, ebx        ; pszExpression
    lea     ebx, [esi-1]    ; length of pszFind -1
   
    ; locate the first char of pszFind in pszExpression
 @Next:
    mov     esi, edx        ; pszFind
    lodsw
    repne   scasw
    jne     @Error          ; not found
   
    ; compare the two strings
    mov     eax, ecx        ; length of pszExpression
    push    edi
    mov     ecx, ebx        ; length of pszFind -1 
    repe    cmpsw

    pop     edi
    mov     ecx, eax        ; length of pszExpression
    jne     @Next           ; not found then to find next first string
   
    ; ok! we're found the pszFind string in pszExpression,then we'll protected following registers
    ;
    ; name  content
    ; ----  --------------------------------------------------------------
    ; edi   destination string
    ; edx   pszFind
    ; ebx   length of pszFind -1
    ; ecx   length of remaining pszExpression after executed repne scasb
    push    edi
    push    edx
    push    ebx
    push    ecx
    ;/
   
    ; start replace
    lea     eax, [edi-2] ; protect pszExpression next
   
    ;
    ; store the string to memory which back of pszFind string in remaining pszExpression
   
    ; search NULL in remaining pszExpression
    lea     edi, [edi+ebx*2]
    mov     edx, edi        ; end of pszExpression
    xor     ecx, ecx
    dec     ecx
    mov     ebx, eax        ; protect pszExpression next
    xor     eax, eax
    repne   scasw
    not     ecx
    shl     ecx, 1
   
    push    ecx
   
    ; proected string to memory which back of pszFind string in remaining pszExpression
    lea     edi, szBuf
    mov     esi, edx
    mov     edx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, edx
    and     ecx, 3
    rep     movsb
    ;/
   
    ;/
    ; replace the pszFind string with pszReplaceWith in remaining pszExpression
    ;
    ; search NULL in pszReplaceWith
    mov     edi, DWORD ptr [pszReplaceWith]
    test    edi, edi
    jz      @RepStrIsNull
    mov     edx, edi
    xor     ecx, ecx
    dec     ecx
    xor     eax, eax
    repne   scasw
    not     ecx
    dec     ecx
    shl     ecx, 1
   
    ; replace pszFind string in remaining pszExpression with pszReplaceWith
    mov     edi, ebx
    mov     esi, edx
    mov     edx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, edx
    and     ecx, 3
    rep     movsb
    jmp     @ReplaceOk
    ;//
   
 @RepStrIsNull:
    mov     edi, ebx
    mov     WORD PTR [edi], 0000h
    add     edi, 2
    xor     edx, edx
    add     edx, 2
 @ReplaceOk:
 
    ; search NULL in pszReplaceWith
    pop     ecx
   
    ; replace pszFind string in remaining pszExpression with pszReplaceWith
    lea     esi, szBuf
    mov     ebx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, ebx
    and     ecx, 3
    rep     movsb
   
    mov     eax, edx    ; length of pszReplaceWith
   
    pop     ecx
    pop     ebx
    pop     edx
    pop     edi
   
    lea     edi, [edi+eax-2]
   
    mov     eax, ecx ; remaining bits of pszExpression to no complete search task
    dec     eax
    cmp     eax, ebx
    ja      @Next    ; continue
    jmp     @Exit
   
 @Error:
    xor     eax, eax    ; not found any chars

 @Exit:
    ret
   
MStrRepW endp


;///

2、ANSI version:

;///
MStrRepA proc uses esi edi ebx pszExpression:DWORD, pszFind:DWORD, pszReplaceWith:DWORD, nStart:DWORD, nCount:DWORD

    local szBuf[1024]:byte

    ; check the pszExpression string whether empty
    mov     eax, DWORD ptr [pszExpression]
    or      eax, eax
    jz      @Error
   
    ; check the pszFind string whether empty
    mov     edx, DWORD ptr [pszFind]
    or      edx, edx
    jz      @Error
   
    cld
   
    ; add nStart
    mov     ebx, eax                    ; first addr of pszExpression
    mov     eax, DWORD PTR [nStart]
    inc     eax
    je      @IsZeroSide
    dec     eax
    lea     ebx, [ebx+eax]            ; start pos from pszExpression
  @IsZeroSide:
 
    ; search length of pszFind
    mov     edi, edx                    ; search pszFind
    xor     ecx, ecx
    dec     ecx
    xor     al, al
    repne   scasb
    not     ecx
    dec     ecx         ; length of pszSrc
    jz      @Error      ; if has not any chars then go to final
   
    mov     esi, ecx    ; backup the length of pszFind

    ; check the length of pszExpression string whether less than length of pszFind string
    mov     edi, ebx    ; pszExpression
    xor     ecx, ecx
    dec     ecx
    xor     al, al
    repne   scasb
    not     ecx
    mov     eax, DWORD PTR [nCount]
    inc     eax
    je      @IsWhole
    cmp     eax, ecx
    ja      @IsWhole
    mov     ecx, eax
  @IsWhole:
    mov     eax, ecx
    cmp     eax, esi
    jbe     @Error
   
    mov     edi, ebx        ; pszExpression
    lea     ebx, [esi-1]    ; length of pszFind -1
   
    ; locate the first char of pszFind in pszExpression
 @Next:
    mov     esi, edx        ; pszFind
    lodsb
    repne   scasb
    jne     @Error          ; not found
   
    ; compare the two strings
    mov     eax, ecx        ; length of pszExpression
    push    edi
    mov     ecx, ebx        ; length of pszFind -1 
    repe    cmpsb

    pop     edi
    mov     ecx, eax        ; length of pszExpression
    jne     @Next           ; not found then to find next first string
   
    ; ok! we're found the pszFind string in pszExpression,then we'll protected following registers
    ;
    ; name  content
    ; ----  --------------------------------------------------------------
    ; edi   destination string
    ; edx   pszFind
    ; ebx   length of pszFind -1
    ; ecx   length of remaining pszExpression after executed repne scasb
    push    edi
    push    edx
    push    ebx
    push    ecx
    ;/
   
    ; start replace
    lea     eax, [edi-1] ; protect pszExpression next
   
    ;
    ; store the string to memory which back of pszFind string in remaining pszExpression
   
    ; search NULL in remaining pszExpression
    lea     edi, [edi+ebx]
    mov     edx, edi        ; end of pszExpression
    xor     ecx, ecx
    dec     ecx
    mov     ebx, eax        ; protect pszExpression next
    xor     al, al
    repne   scasb
    not     ecx
   
    push    ecx
   
    ; proected string to memory which back of pszFind string in remaining pszExpression
    lea     edi, szBuf
    mov     esi, edx
    mov     edx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, edx
    and     ecx, 3
    rep     movsb
    ;/
   
    ;/
    ; replace the pszFind string with pszReplaceWith in remaining pszExpression
    ;
    ; search NULL in pszReplaceWith
    mov     edi, DWORD ptr [pszReplaceWith]
    test    edi, edi
    jz      @RepStrIsNull
    mov     edx, edi
    xor     ecx, ecx
    dec     ecx
    xor     al, al
    repne   scasb
    not     ecx
    dec     ecx
   
    ; replace pszFind string in remaining pszExpression with pszReplaceWith
    mov     edi, ebx
    mov     esi, edx
    mov     edx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, edx
    and     ecx, 3
    rep     movsb
    jmp     @ReplaceOk
    ;//
   
 @RepStrIsNull:
    mov     edi, ebx
    mov     BYTE  PTR [edi], 00h
    inc     edi
    xor     edx, edx
    inc     edx
 @ReplaceOk:
 
    ; search NULL in pszReplaceWith
    pop     ecx
   
    ; replace pszFind string in remaining pszExpression with pszReplaceWith
    lea     esi, szBuf
    mov     ebx, ecx
    shr     ecx, 2
    rep     movsd
    mov     ecx, ebx
    and     ecx, 3
    rep     movsb
   
    mov     eax, edx    ; length of pszReplaceWith
   
    pop     ecx
    pop     ebx
    pop     edx
    pop     edi
   
    lea     edi, [edi+eax-1]
   
    mov     eax, ecx ; remaining bits of pszExpression to no complete search task
    dec     eax
    cmp     eax, ebx
    ja      @Next    ; continue
    jmp     @Exit
   
 @Error:
    xor     eax, eax    ; not found any chars

 @Exit:
    ret
   
MStrRepA endp

;///

注意!由于在下的机器是NT内核的XP SP2系统,故主要都是编写倾向于UNICODE软件,所以推荐大家使用UNICODE版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值