前回はCBWとCWDでした。今回はCMC、CLCとSTCです。似たような3文字ニーモニックの命令が続きますが他意はありません。x86は3文字ニーモニックの命令が多いだけのこと。今回の3命令に共通するのは末尾のCです。CARRY FLAGのCです。キャリーフラグ(CF)を操作したいことがそれだけ多いってこってす。
※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら
※実機動作確認(といってもエミュレータなんだけれども)には以下を使用させていただいております。
今回練習してみる命令ども
以下の3命令は全て1バイト命令で、オペランドもとりませぬ。
-
- CMC、キャリフラグ(CF)のCOMPLEMENTをとる命令。実行するとCFの値が反転(トグル)する。
- CLC、CFをCLEARする命令。実行するとCFの値が0になる。
- STC、CFをSETする命令。実行するとCFの値が1になる。
ADD、SUBなどの算術演算だけでなく、シフトローテイト系の命令などCFが活躍する命令は数多く、いくつかあるフラグの中でデータの処理に一番活躍するフラグでないかと思います。
オペコード(部分)が以下に。1等地のファースト・バイトに3バイトを使っています。優遇されている感じ。
今回実験のプログラム
強力なx86用アセンブラNASM用のソースです。フラグの値はデバッガでトレース実行して確認する予定なので、だらだらとCFを上げたり下げたりするだけのプログラムです。
segment code ..start: mov ax, data0 mov ds, ax mov es, ax mov ax, stack mov ss, ax mov sp, stacktop test: stc clc cmc stc cmc fin: mov ax, 0x4c00 int 0x21 resb 2048 segment data0 align=16 resb 1024 * 63 segment stack class=STACK align=16 resb 2048 stacktop: dw 1024 dup (0) stackend:
コマケー話を書いておくと、ターゲットプログラムのスタックはstacktopから下へ伸びていきますが、それ以前にOSがデバッガを起動した後、プログラムをメモリに割付したりする過程でそれより上のアドレス(stackendから下)のスタックを使うようなのでどちらのスタック操作か識別できるようにちょいとメンドイ書き方してます。
アセンブルして実行
MS-DOS互換で機能強化されてるフリーなFreeDOS上、以下のステップで上記のアセンブラソースcy.asm から実行可能なオブジェクトファイルを生成して実行することができます(nasmとwatcom Cがインストール済であること。)
nasm -f obj -l cy.lst cy.asm wlink name cy.exe format dos file cy.obj debug cy.exe
デバッガ起動後、今回のプログラムの逆アセンブルを行ったところ。
さて、テストの冒頭のSTC命令から実行してみます。同じ色の枠が、観察対象の命令とその命令の結果として上げ下げされるキャリーフラグの様子を表してます。CYはキャリーが1、NCはキャリーが0の意味です。
予定通りの挙動であるのう。何の問題もない。