
x86(16bit)のオペコードマップの「塗りつぶし」も見た目は後一息という雰囲気を醸してます。今回は過去回でMOVSのみ練習して他の命令どもから目を背けていたストリング命令の残りからSCASとCMPSを練習してみます。メモリの中から特定のパターンを見つけたり文字列同士の比較に威力を発揮するもの。まあCISCらしい。
※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら
※実機動作確認(といってもエミュレータなんだけれども)には以下を使用させていただいております。
SCASとCMPS
SCASは、バイトの場合AL、ワードの場合AXレジスタに値を入れ、ES:DIにメモリアドレスを、CXに調べる回数をロードして呼び出すとメモリを「舐めて」一致、不一致を調べてくれる命令です。プリフィックスREPZを付加すれば比較結果が一致しているかCXが0でない間同じ動作を繰り返し、REPNZを付加すれば比較結果が一致しないかCXが0でない間繰り返します。勿論、アドレスの更新方向はFlagsのDF(ディレクション・フラグ)によって決定されます。ちょいメンドイけど便利ね~。
CMPSは、DS:SIに第1のメモリアドレスをES:DIに第2のメモリアドレスを入れ、CXに比較回数をロードして呼び出すとメモリ同士を比較して、一致、不一致を調べてくれる命令です。プリフィックスREPZを付加すれば比較結果が一致しているかCXが0でない間同じ動作を繰り返し、REPNZを付加すれば比較結果が一致しないかCXが0でない間繰り返します。やはりアドレスの更新方向はFlagsのDF(ディレクション・フラグ)によって決定されます。
なお、REPZをREPEと綴ってもよいし、REPNZをREPNEと綴るのもありです。
今回実験のプログラム
強力なx86用アセンブラNASM用のソースです。メモリにおいた “Hello world.”復帰改行と”Hello World.”復帰改行を使って通り一遍の比較を行うだけのもの。
segment code ..start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, stacktop mov ax, edata mov es, ax test1: mov di, dstblk mov al, 'W' mov cx, 15 cld repnz scasb test2: mov si, srcblk mov di, dstblk mov cx, 15 cld repz cmpsb fin: mov ax, 0x4c00 int 0x21 resb 2048 segment data align=16 resb 1024 * 63 srcblk: db 'Hello world.',13,10,'$',0 segment edata align=16 resb 1024 * 63 dstblk: db 'Hello World.',13,10,'$',0 segment stack class=STACK align=16 resb 2048 stacktop: dw 1024 dup (0) stackend:
アセンブルして実行
MS-DOS互換で機能強化されてるフリーなFreeDOS上、以下のステップで上記のアセンブラソース scas.asm から実行可能なオブジェクトファイルを生成して実行することができます(nasmとwatcom Cがインストール済であること。)
nasm -f obj -l scas.lst scas.asm wlink name scas.exe format dos file scas.obj debug scas.exe
デバッガ起動後、今回のプログラムの逆アセンブルを行ったところ。
この一命令にて、whileループ1個分の働きがあると思えば強力。
上がDS:SIでポイントする方、下がES:DIでポイントする方です。7文字目のwが上は小文字、下は大文字であることをご確認くだされや。
さて以下はES:DIに対して大文字 ‘W’ をみつけるためのSCASを発行したときのもの。なお、SCASを含むストリング命令群は全てREPの途中で割り込みを受け付けるので、「トレース」すると一周毎に止まってくれます。
上記を見るとDIがFC07のところで大文字Wを発見してREPの繰り返しを脱出してきたことが分かります。
お次はCMPS、DS:SIとES:DIを比較するもの。当然7文字目が w と W で差異があるので、そこが不一致になる筈。
予定通りの挙動ぞなもし。