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

Joseph Halfmoon

前回はファーポインタをレジスタ組にロードするLESとLDSでした。今回は符合拡張を行うCBWとCWDです。8086らしいなと思うのは、この命令、明示的なオペランドをとりません。レジスタはキメウチ、アキュムレータのみです。この辺のレジスタの使い方に偏りがあるのが御先祖に8ビットを頂くx86らしさかと。

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

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

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
CBWとCWD

オペコード・マップ上の2命令の位置が以下に。CBW_CWD_opcodeMap

どちらも整数の符号拡張命令です。

    • CBWは、ALレジスタのバイト(8ビット)の符号付整数値を符号拡張してAXレジスタのワード(x86では16ビット)とする(AHレジスタを符号で埋める)
    • CWDは、AXレジスタのワード(16ビット)の符号付整数値を符号拡張してDX:AXレジスタレジスタのダブルワード(x86では32ビット)とする。なお符号拡張結果の32ビット幅の値の上位16ビット(符号ビットを繰り返し並べたもの)がDXに格納される。下位16ビットを保持するAXはそのまま。

AX(その下位8ビットがAL)がアキュムレータとして一身にお役目を担っております。そしてDXがアキュムレータAXの上位となるのもお約束。

今回実験のプログラム

強力なx86用アセンブラNASM用のソースです。CBW、CWDともに入力値は元のビット幅の正の最大値と、負の最小値の2通りを通してます。また「書き替えられる」レジスタ、CBWではAH、CWDではDXに、書き替えられたことが明確になるように0x55または0x5555を入れてあります。

segment code

..start:
    mov ax, data0
    mov ds, ax
    mov es, ax
    mov ax, stack
    mov ss, ax
    mov sp, stacktop
test:
    mov ax, 0x557F
    cbw
    mov ax, 0x5580
    cbw
    mov dx, 0x5555
    mov ax, 0x7FFF
    cwd
    mov dx, 0x5555
    mov ax, 0x8000
    cwd
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:
アセンブルして実行

MS-DOS互換で機能強化されてるフリーなFreeDOS上、以下のステップで上記のアセンブラソースcbwcwd.asm から実行可能なオブジェクトファイルを生成して実行することができます(nasmとwatcom Cがインストール済であること。)

nasm -f obj -l cbwcwd.lst cbwcwd.asm 
wlink name cbwcwd.exe format dos file cbwcwd.obj
debug cbwcwd.exe

以下は、対象のオブジェクトコードをデバッガで逆アセンブルしたものです。u00000028EC

以下の最初のケースは、バイト幅からの符号拡張。赤枠がバイト型の符号付整数の最大値127(0x7F)をワード型に符号拡張するもの。緑枠がバイト型の符号付整数の最小値-128(0x80)をワード型に符号拡張するもの。CBW_EC

お次は、ワード幅からのの符号拡張。赤枠がワード型の符号付整数の最大値32767(0x7FFF)をダーブルワード型に符号拡張するもの。CWDp_EC

最後は、ワード幅からのの符号拡張。赤枠がワード型の符号付整数の最小値ー32768(0x8000)をダーブルワード型に符号拡張するもの。CWDn_EC

符号拡張できましたな。ここでもアキュムレータ大活躍だったな、8086。

ぐだぐだ低レベルプログラミング(201)x86(16bit)、LES、LDS へ戻る

コメントを残す

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