比較や検索
データ列を比較
ストリング操作命令とリピートプリフィックスを用いて
メモリの指定領域どうしのデータの比較を行うことができます
メモリ内のデータを比較するには CMPS を用います
やはり、魅力的なのはリピートリフィックスを用いて連続的に比較できることと
汎用レジスタを介さずに、高速に処理することができることです
CMPS は明示オペランド形式で、仕様はMOVSと同じです
オペランドなし形式では、バイトサイズのCMPSBと、ワードサイズのCMPSWがあります
これらは指定されたサイズで、SIレジスタが指すオフセットアドレスの内容と
DIレジスタが指すオフセットアドレスの内容を比較します
つまり、次のような関係があります
CMPSB
| =
|
CMP [SI] , [DI]
INC(DEC) SI
INC(DEC) DI
|
---|
通常は、単独として用いるよりもリピートプリフィックスを用いて使います
たとえば、REPNZ を用いれば比較した内容が等しくなるまでストリング命令を繰り返します
-E 200 "ABCDE"
-E 300 "EDCBA"
-A 100
15F2:0100 MOV SI , 200
15F2:0103 MOV DI , 300
15F2:0106 MOV CX , 5
15F2:0109 CLD
15F2:010A REPNZ CMPSB
15F2:010C
-G =100 10C
AX=0000 BX=0000 CX=0002 DX=0000 SP=FFEE BP=0000 SI=0203 DI=0303
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=010C NV UP EI PL ZR NA PE NC
まず、E コマンドでオフセットアドレス 200 から "ABCDE" というデータ列を
オフセットアドレス 300 から "EDCBA" というデータ列を保存します
その後、REPNZ CMPSB とすることで、常にSIとDIのアドレスを比較しながら繰り返し
双方が等しい場合は ZF フラグが 1 となり処理が終了します
実行後の SI と DI をみると、オフセットアドレス 202 と 302 を最後に比較して終了していることがわかります
データの検索
ストリング操作命令の強力な機能の一つに検索があります
メモリの指定範囲にあるデータがないかを検索するには、ストリング操作が有効です
データの検索には SCAS 命令を用います
SCAS は明示オペランド形式で、レジスタと DI のオフセットアドレスを比較します
SCAS は第一オペランドに、サイズを指定します
サイズがバイトであれば、AL レジスタと、ワードであれば AX レジスタと
DI レジスタが指すオフセットアドレスを比較します
オペランドなし形式では、バイトサイズがSCASB、ワードサイズがSCASWです
これまで同様に、サイズによって比較するレジスタとメモリのサイズが決定します
これらは、次のような関係でもあります
SCASB
| =
|
CMP AL , [DI]
INC(DEC) DI
|
---|
SCAS 命令も、通常はリピートプリフィックスと併用します
REPNE 等を用いれば、レジスタの内容と
DI レジスタが指すオフセットアドレスの内容が等しい位置を検索できます
-E 200 "Kitty on your lap"
-A 100
15F2:0100 MOV AL , 79
15F2:0102 MOV DI , 200
15F2:0105 MOV CX , 11
15F2:0108 CLD
15F2:0109 REPNE SCASB
15F2:010B
-G =100 10B
AX=0079 BX=0000 CX=000C DX=0000 SP=FFEE BP=0000 SI=0000 DI=0205
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=010B NV UP EI PL ZR NA PE NC
-D 204 , 204
15F2:0200 79 y
オフセットアドレス 200 から検索を開始しています
AL レジスタには16進数の 79、ASCIIコードの小文字の y にあたります
実行後、DIを調べると 205 であることがわかります
つまり、204 の位置まで実行して終了したということですね