ぐだぐだ低レベルプログラミング(228)x86(16bit)、整数のFPUレジスタ上の表現

Joseph Halfmoon

前回まで8087FPUの浮動小数を扱う命令ばかり練習してきました。でもFPUにも整数をロード/ストアする命令があるのです。しかし整数を演算する命令というのは不在。FPUレジスタにロードしてしまえばどんな整数も強力なテンポラリReal型に収まってしまうみたいです。今回はその様子を前回やったFXTRACT命令使って観察。

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

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

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
整数ロード命令

整数のロード命令として、浮動小数のロード命令のニーモニック FLD に一文字を挿入した以下の2つの命令が存在します。

    • FILD、通常のバイナリ整数(2の補数)ロード
    • FBLD、BCD形式の整数ロード

今回はフツーの整数ということでFILD命令だけ練習です。「パックド」なBCD(バイナリ・コーデッド・デシマル)整数はフツーの整数を一通りやったあとね。

FPUが取り扱える2の補数の整数型は以下のようです。なお、x86の場合、ワードは16ビットのことなのでお間違えなく。

    • ワード(16ビット)整数
    • ショート(32ビット)整数
    • ロング(64ビット)整数

の3とおりです。アセンブラ的にはFILD命令のオペランドに DWORD PTR(ダブルワードへのポインタ)などとポインタ修飾指定することでワード、ショート、ロングのオペランド選択が行えます。

今回実験のプログラム

今回はFILD命令で、メモリ上に置かれた整数(当然、いつもの整数デス。CPU側で読んでも同じ整数値に見えるもの)をFPUのレジスタスタックにロード後、前回も使ってみたFXTRACT命令を発行し、仮数部と指数部に分離してその値を眺めてみます。

    • ロードする整数値は 55771、ただしポインタはDWORD PTRで指すので「ショート(32ビット整数)」扱い

なお以下は「強力なx86用アセンブラNASM」用のソースです(MSのMASMともインテルASM86とも微妙に異なるけど、まあ分かるっしょ。)

%use fp

segment code
..start:
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax
    mov sp, stacktop
test:
    mov bx, src1
    fild dword [bx]
    fxtract
fin:
    mov ax, 0x4c00
    int 0x21
    resb    2048

segment data    align=16
    resb    1024 * 63
src1: dd 55771

segment stack   class=STACK align=16
    resb    2048
stacktop:
    dw 1024 dup (0)
stackend:
アセンブルして実行

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

なお、FreeDOS付属の「debugx」デバッガは、8087のレジスタ内容を浮動小数で見せてくれます

nasm -f obj -l fild.lst fild.asm
wlink name fild.exe format dos file fild.obj
debugx fild.exe

まずはプログラムの逆アセンブルリスト。filduasm

まずは、FILD命令でBXレジスタで指定されているメモリ上の32ビット「ショート整数」をロードするところ。FILD

FILD命令のオペランド指す、DS:FC00=0000D9DB(16進)は、10進に直すと55771です。FILD実行後、FPUのレジスタスタックのST0に「55771」という「整数相当」なピッタンコな値が入ってます。

ここでFXTRACT命令を発行してみます。FXTRACT

緑色の箱のST0に仮数部、ST1に指数部(下駄履き無)が格納されてます。整数ロードしたけれどもFPUレジスタ的には

1.7019958496093750 * 2^15

という浮動小数点数値がロードされたのと等価です。念のためにWindowsの電卓で検算すれば以下のごとし。2の15乗は32768ですぞ、念のため。

RESULT

確かに「ピタリ」の整数と等価な値。お陰で浮動小数点数でも整数でも演算は思いのままだと。

ぐだぐだ低レベルプログラミング(227)x86(16bit)、指数部の操作あれこれ へ戻る

コメントを残す

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