News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Bug in szCmpi

Started by davk, June 25, 2005, 09:24:38 PM

Previous topic - Next topic

davk

While messing around with the findfile example and converting
the api calls to masm32 library calls I found that szCmpi returns
an identical comparison with different strings when it exits
due to the not equal comparison below and the position the
strings differ is equal to the input length.

The following is the main code of szCmpi with comments and extra
code added.



  ;....

  @@:

    lea ebx, table      ; table base address
    mov esi, src        ; 1st string in ESI
    mov edi, dst        ; 2nd string in EDI
    mov ecx, ln         ; length in ECX
    add ecx, esi        ; add ESI to get exit condition

  @@:
    mov al, [esi]       ; get 1st byte
    inc esi
    xlatb               ; replace it with byte in table
    mov ah, al          ; store it in AH
    mov al, [edi]       ; get 2nd byte
    inc edi
    xlatb               ; replace it with byte in table
    cmp ah, al          ; compare if equal
    jne @F              ; jump out if not equal
    cmp esi, ecx        ; exit on length
    jl @B

    ; String identical up to length, exit 'identical'.

    xor eax, eax        ; <- added
    jmp @@Exit          ; <- added


  @@:

    ; Strings not identical, return position they differ.
    ;
    ; As esi is incremented after the character load, if
    ; the input length corresponds then the if condition
    ; test below leaves with the strings read as identical
    ; when they are not.

    sub esi, src

    ;.if esi == ln
    ;  xor eax, eax
    ;.else
      mov eax, esi
    ;.endif

@@Exit:

    pop edi
    pop esi
    pop ebx

    ret

szCmpi endp



MichaelW

Yes, I verified this behavior. The position of the first mismatch is returned only if the count includes a second mismatch.

    include \masm32\include\masm32rt.inc
    .data
        src db "abcdef",0
        dst db "abcdyz",0
    .code
start:
    FOR cnt,<1,2,3,4,5,6>
      invoke szCmpi,ADDR src,ADDR dst,cnt
      movzx  ecx,src+cnt-1
      movzx  edx,dst+cnt-1
      invoke crt__cprintf,chr$("src:%c dst:%c rval:%d",10),ecx,edx,eax
    ENDM
    mov   eax, input(13,10,"Press enter to exit...")
    exit
end start


src:a dst:a rval:0
src:b dst:b rval:0
src:c dst:c rval:0
src:d dst:d rval:0
src:e dst:y rval:0
src:f dst:z rval:5

eschew obfuscation

hutch--

#2
Thanks for finding the problem, I have not visited this algo for years so its about time I had a good look at it.

LATER :

I have partially rewriten the algo as I could find an error if the last characters was a mismatch which it did not report. I have attached a test piece that has the suggested replacement in it. It appears to be working OK but I may not have understood the example properly. The loop code is a bit cleaner as well so it may be slightly faster.

[attachment deleted by admin]
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

The new version seems to work OK. I altered my test code to also test the case insensitivity, and ln values greater than the length of the strings.

    include \masm32\include\masm32rt.inc

    szCmpix PROTO :DWORD,:DWORD,:DWORD

    .data
        srcx db "aBcDefG",0,0
        dstx db "abCdYz",0,0,0
    .code
start:
    FOR cnt,<1,2,3,4,5,6,7,8,9>
      invoke szCmpix,ADDR srcx,ADDR dstx,cnt
      movzx  ecx,srcx+cnt-1
      movzx  edx,dstx+cnt-1
      invoke crt__cprintf,chr$("src:%c dst:%c rval:%d",10),ecx,edx,eax
    ENDM
    mov   eax, input(13,10,"Press enter to exit...")
    exit


src:a dst:a rval:0
src:B dst:b rval:0
src:c dst:C rval:0
src:D dst:d rval:0
src:e dst:Y rval:5
src:f dst:z rval:5
src:G dst:  rval:5
src:  dst:  rval:5
src:  dst:  rval:5

eschew obfuscation

hutch--

Michael,

Thanks for testing it, it has been testing OK here as well so its probably safe to add back into the library.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php