ストリング操作


データ列の転送

プログラムをしていると、データの列を扱うことがしばしばあります
文字列の転送や、検索、置き換えなど様々ですね

このような動作は、比較やループを用いて行うことも可能ですが非常に厄介で動作も遅いのです
//短いサイクルでは、体感できるほどの差はないですが…
しかし、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 は定義上の問題で実装の必要はありません



前のページへ戻る次のページへ