ストリング操作
データ列の転送
プログラムをしていると、データの列を扱うことがしばしばあります
文字列の転送や、検索、置き換えなど様々ですね
このような動作は、比較やループを用いて行うことも可能ですが非常に厄介で動作も遅いのです
//短いサイクルでは、体感できるほどの差はないですが…
しかし、i86にはデータ列を専門に扱うストリング操作命令というものがあります
この命令を用いれば、レジスタを介入させずにデータの転送が行えます
ストリング操作命令で代表的なものが MOVSB 命令です
MOVSB には、オペランドは指定しません
この命令は、SIレジスタのオフセットアドレスの内容をDIレジスタのオフセットアドレスにコピーします
そしてその後、SIレジスタとDIレジスタの内容をインクリメント、またはデクリメントします
つまり、次のような関係があります
MOVSB
| =
|
MOV AL , [SI]
MOV [DI] , AL
INC(DEC) SI
INC(DEC) DI
|
---|
ストリング操作命令を使うと、実際にALレジスタを介して転送するより高速に動作します
SIとDIを最後にインクリメントするか、またはデクリメントするかの判断は
フラグレジスタの一つ、DFレジスタで決定されます
DFフラグが 0 であれば、それぞれのポインタをインクリメントし
DFフラグが 1 であれあ、デクリメントとなります
このフラグのセットや解除は、専用の命令を使います
DFフラグを解除にするには CLD、セットするにはSTDを使います
両方とも、オペランドの指定はありません
-A 100
15F2:0100 MOV BYTE PTR[200] , 41
15F2:0105 MOV SI , 200
15F2:0108 MOV DI , 300
15F2:010B CLD
15F2:010C MOVSB
15F2:010D
-G =100 10D
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0201 DI=0301
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0110 NV UP EI PL NZ NA PO NC
-D 200 200
15F2:0200 41 A
-D 300 300
15F2:0300 41 A
オフセットアドレス 200 に 41 を設定して、それをアドレス 300 に転送しています
まず、重要なことの一つは汎用レジスタを介さずに転送ができるということです
また、SIとDIレジスタの内容を見ればわかりますが、インクリメントされていることも確認できます
DFフラグレジスタを、STDによってセットしていれば逆にデクリメントされることが確認できるでしょう
さらに、MOVSB は1バイトのデータ転送でしたが、ワード単位で転送することもできます
同様の操作をワード単位で行うには MOVSW 命令を使います
この命令を使用した場合、SIとDIのそれぞれのレジスタが
インクリメント、またはデクリメントされるときにワード単位(つまり2)で行われます
-A 100
15F2:0100 MOV WORD PTR[200] , 4241
15F2:0106 MOV SI , 200
15F2:0109 MOV DI , 300
15F2:010C CLD
15F2:010D MOVSW
15F2:010E
-G =100 10E
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0202 DI=0302
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=010E NV UP EI PL NZ NA PO NC
-D 200 201
15F2:0200 41 42 AB
-D 300 301
15F2:0300 41 42 AB
1度の命令実行で2バイト転送されているのが確認できますね
さらに、この命令の実行に対するクロック数は同じなので
大量のデータを転送するときは、ワード単位で転送すると倍の速さで転送できます
余談であるかもしれないが、これらの命令はMOVSと呼ばれる命令のショート形式でもあります
MOVS は、MOVSB などと異なりソースとディスティネーションをしていしなければいけません
MOVS ソース , ディスティネーション
しかし、ストリング操作命令の対象は常にSIとDIレジスタです
ここで指定するのは、対象ではなくオペランドのサイズです
アセンブラは、ここで指定されたサイズを元にバイト単位かワード単位か決定できます
この形式を明示オペランド形式と呼び
MOVSBのようなショート型をオペランドなし形式と呼びます
しかし、通常は MOVS は定義上の問題で実装の必要はありません