2017-10-31 13 views
1

文字列の各文字を取得し、別の文字列の各文字と比較するプログラムを作成することを意味しています。基本的には、他の文字列の前記文字のインスタンスをカウントします。アセンブリ内で文字列の各文字を別の文字列に検索する方法

私の問題は、最初の文字列の2番目の文字以降では機能しないようです。いずれかのエラーが発生するか、またはのカウントがと等しい。

助けてください。どうもありがとうございます!

mov ecx, [len2]    ; length of name2 
    mov esi, name1 
    mov edi, name2 

    mov byte[count], 0   ; counts instance 
    cld 

    loop1: 
     lodsb     ; loads letter in name1 
     loop2: 
      cmp ecx, 0 
      jne cont1 

      mov ecx, [len2]  
      loop loop1 

      cont1: 
       scasb   ; compares character in al to every char in name2 
       jne cont2 

       inc byte[count] 
      cont2: 
       loop loop2 
+2

このコードは 'scasb'' [LEN2] '回行うと、問題のない'ループloop2'、後に次の命令を続けるので、それもlodsb'秒 'になるだろうか明らかではないでしょう時間をかけたり、 'name1'をループします。 'cmp ecx、0'が' ecx'でゼロを捕まえる可能性があるならば 'name1'をどれくらいの期間ループしたいのかは明らかではありません(' loop loop2'は ' ecx == 0')、それを '[len2]'に再び復元するので、 'lodsb'や' scasb'が無効なメモリアクセスでクラッシュするまで、 'loop loop1'は常にループします(無限ループ)。デバッガはありませんか?難しいです。 – Ped7g

+1

これを半効率的にするには、[ループのための 'loop'命令を避けてください](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel- have-implemented-it-efficient)、ループカウンタをメモリに保持しないでください。 'ebx'を含め、使用していないレジスタがたくさんあります。 –

+0

*実際に*効率的にしたいなら、あなたがチェックしているセットから複数の*文字に対してロードする各文字をチェックする方法を見つけ出してください。放送するために '0x01010101'を掛けたように、一度に4バイトとの一致を確認することができます。 (xorを使用し、0バイトのチェックビットを使用してください。https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord)SSE2またはSSE4.2を使用してください。 SSE4.2 pcmpistriは実際にはこの種の問題に適しています。 16の候補を一度に照合するために16バイトをチェックするために使用することができます。 https://www.strchr.com/strcmp_and_strlen_using_sse_4.2 –

答えて

0
cmp ecx, 0 
jne cont1 

空の場合は、なぜあなたは場合は第二の文字列をテストし続けるだろうか?それは一度だけ行います。

mov ecx, [len2]  
loop loop1 

命令のこのペアは場違いです。 2番目の文字列を完全に実行した後にする必要があります。

次の改良版である:まだここに何が不足しているか

mov byte[count], 0 ; counts instance 
    cmp dword[len2], 0 ; length of name2 
    je EndIt 
    mov esi, name1 
    mov edi, name2 
    cld 
loop1: 
    lodsb     ; loads letter in name1 
    mov ecx, [len2]  
loop2: 
    scasb     ; compares character in al to every char in name2 
    jne NotEQ 
    inc byte[count] 
    NotEQ: 
    dec ecx 
    jnz loop2 
    jmp loop1 
EndIt: 

は、あなたが外側のループを停止する方法です。

おそらく、最初の文字列がゼロ終了を使用していますか?

lodsb     ; loads letter in name1 
    cmp al, 0 
    je EndIt 
関連する問題