; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

 .486             ; 32-bit instruction set
 .model flat      ; Protected memory, 4GB limit
 .code            ; Start of code

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

align 4 ; Adapted from StrLen algorithm written by Agner Fog :)

StrLenW proc ; lLen = StrLenW(sStr)

    push    esi
    push    ebx

    mov     esi, [esp+16]        ; get pointer to string
    mov     eax, [esi]
    test    eax, eax             ; test for zero pointer
    jz      exitp                ; exit if null string

    mov     ebx, 80008000h       ; mask word sign bits
    mov     esi, eax             ; copy pointer

  scan:
    mov     edx, [eax]           ; read next 2 words
    add     eax, 4               ; increment dword pointer
    lea     ecx, [edx-00010001h] ; subtract 1 from each word
    not     edx                  ; invert all bytes
    and     ecx, edx             ; and these two
    and     ecx, ebx             ; test MSBit of each word
    jz      scan                 ; no zero words, continue loop

    sub     eax, esi             ; subtract start address
    shr     eax, 1               ; convert to char count
    shl     cx,  1               ; use carry flag to avoid branch
    sbb     eax, 1               ; compute length

  exitp:

    mov     edx, [esp+20]
    mov    [edx], eax            ; return result

    pop     ebx
    pop     esi
    xor     eax, eax

    ret     12

StrLenW endp

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

end StrLenW
