ぐだぐだ低レベルプログラミング(203)x86(16bit)、CMC、CLC、STC

Joseph Halfmoon

前回はCBWとCWDでした。今回はCMC、CLCとSTCです。似たような3文字ニーモニックの命令が続きますが他意はありません。x86は3文字ニーモニックの命令が多いだけのこと。今回の3命令に共通するのは末尾のCです。CARRY FLAGのCです。キャリーフラグ(CF)を操作したいことがそれだけ多いってこってす。

※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら

※実機動作確認(といってもエミュレータなんだけれども)には以下を使用させていただいております。

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
今回練習してみる命令ども

以下の3命令は全て1バイト命令で、オペランドもとりませぬ。

    1. CMC、キャリフラグ(CF)のCOMPLEMENTをとる命令。実行するとCFの値が反転(トグル)する。
    2. CLC、CFをCLEARする命令。実行するとCFの値が0になる。
    3. STC、CFをSETする命令。実行するとCFの値が1になる。

ADD、SUBなどの算術演算だけでなく、シフトローテイト系の命令などCFが活躍する命令は数多く、いくつかあるフラグの中でデータの処理に一番活躍するフラグでないかと思います。

オペコード(部分)が以下に。1等地のファースト・バイトに3バイトを使っています。優遇されている感じ。opcodeCMC_CLC_STC

今回実験のプログラム

強力な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

デバッガ起動後、今回のプログラムの逆アセンブルを行ったところ。disasm

さて、テストの冒頭のSTC命令から実行してみます。同じ色の枠が、観察対象の命令とその命令の結果として上げ下げされるキャリーフラグの様子を表してます。CYはキャリーが1、NCはキャリーが0の意味です。CMC_CLC_STC

予定通りの挙動であるのう。何の問題もない。

ぐだぐだ低レベルプログラミング(202)x86(16bit)、CBW、CWD へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です