dword比較を使用するコードは次のとおりです。
それは最初に文字列の長さをチェックすることに注意してください。これは、前述のライブラリでは文字列に長さのプレフィックスが付いているため、StrLenはインスタントO(1)であり、終了NULLのスキャンはフォールバックとしてのみ提供されます(この回答の2番目の部分を参照)。
実際の比較の前に長さを比較すると、さまざまな文字列の速度をO(1)にすることができます。これにより、大きな配列を検索する場合に、パフォーマンスが大幅に向上する可能性があります。
次に、比較はdwordsで行われ、最後に、文字列の長さが4の乗算でない場合、残りの1..3バイトがバイトごとに比較されます。
proc StrCompCase, .str1, .str2
begin
        push    eax ecx esi edi
        mov     eax, [.str1]
        mov     ecx, [.str2]
        cmp     eax, ecx
        je      .equal
        test    eax, eax
        jz      .noteq
        test    ecx, ecx
        jz      .noteq
        stdcall StrLen, eax
        push    eax
        stdcall StrLen, ecx
        pop     ecx
        cmp     eax, ecx
        jne     .noteq
        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax
        mov     eax, ecx
        shr     ecx, 2
        repe cmpsd
        jne     .noteq
        mov     ecx, eax
        and     ecx, 3
        repe cmpsb
        jne     .noteq
.equal:
        stc
        pop     edi esi ecx eax
        return
.noteq:
        clc
        pop     edi esi ecx eax
        return
endp
StrLenコードについて:
これがStrLenの実装です。
可能であれば、長さのプレフィックス付き文字列を使用していることがわかります。これにより、実行時間がO(1)になります。これが不可能な場合は、1サイクルあたり8バイトをチェックするスキャンアルゴリズムにフォールバックし、かなり高速ですが、それでもO(n)です。
proc StrLen, .hString    ; proc StrLen [hString]
begin
        mov     eax, [.hString]
        cmp     eax, $c0000000
        jb      .pointer
        stdcall StrPtr, eax
        jc      .error
        mov     eax, [eax+string.len]
        clc
        return
.error:
        xor     eax, eax
        stc
        return
.pointer:
        push    ecx edx esi edi
; align on dword
.byte1:
        test    eax, 3
        jz      .scan
        cmp     byte [eax], 0
        je      .found
        inc     eax
        jmp     .byte1
.scan:
        mov     ecx, [eax]
        mov     edx, [eax+4]
        lea     eax, [eax+8]
        lea     esi, [ecx-$01010101]
        lea     edi, [edx-$01010101]
        not     ecx
        not     edx
        and     esi, ecx
        and     edi, edx
        and     esi, $80808080
        and     edi, $80808080
        or      esi, edi
        jz      .scan
        sub     eax, 9
; byte 0 was found: so search by bytes.
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop
.found:
        sub     eax, [.hString]
        clc
        pop     edi esi edx ecx
        return
endp
ゼロで終了する文字列には、パフォーマンスとセキュリティの両方の問題があることに注意してください。
サイズのプレフィックス付き文字列を使用することをお勧めします。たとえば、前述のライブラリは動的文字列を使用します。この場合、文字列には、文字列の現在の長さを含むオフセット-4(上記のコードではstring.len)にdwordフィールドが含まれます。