ぐだぐだ低レベルプログラミング(226)x86(16bit)、絶対値、平方根、符号反転

Joseph Halfmoon

前回の対数関数前々回の指数関数と「素の機械語命令」のままでは定番関数値が直接求まらないので「ひと捻り」必要でした。今回はお楽、スタックトップに置いた値を素直に処理してくれます。浮動小数値の符号反転(FCHS)、絶対値(FABS)、そして平方根(FSQRT)です。ひとよひとよにひとみごろ~。

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

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

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
FCHS、FABS、FSQRT

FCHSは、符号反転命令です。スタックトップの値を正の値ならば負に、負の値ならば正へと変換してくれます。なお浮動小数点数のフォーマット的に+0.0とー0.0という2種類のゼロもあり、FCHS使えばこれらの間の変換も可能。そんなもの何に使うんじゃ?

FABSは、絶対値命令です。スタックトップの値の絶対値(実際には正の値だね)に変換してくれます。入力が負の値ならばその御利益あらたかですが、正の値では分かりませぬなあ。

FSQRTは、スタックトップの値の平方根を計算してくれる命令です。実数の範囲の平方根なので、フツーに正の数の平方根をとれば正の数の筈。唯一の例外はー0.0の平方根をとるとー0.0が返ってくるらしいです。

今回実験のプログラム

機械語命令のテストプログラムを書いているわけでもなんでもないので、今回も、さらっと触ってお茶を濁す所存です。

    1. 2.0のFCHSとってー2.0になることを確認
    2. ー2.0のFABSとって2.0になることを確認
    3. 2.0のFABSとって以下のような√2が登場するのを確認
    • SQRT(2)=1.4142135623730950488016887242097

なお例によって上記はWindows付属の関数電卓で計算した結果です。

なお以下は「強力な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:
    fld1
    fld1
    faddp
    fchs
    fabs
    fsqrt
fin:
    mov ax, 0x4c00
    int 0x21
    resb    2048

segment data    align=16
    resb    1024 * 63

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

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

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

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

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

上記の赤枠内にターゲットの3命令が並んでます。

まずはFCHSによる符号反転から。赤枠のところをご注目くだされ。FCHS

続いてFABSによる絶対値。赤枠のところをご注目くだされ。FABS

最後にFSQRTによる平方根。FSQRT

スタックトップを眺めれば、「ひとよひとよにひとみごろ~」とくらあ。

ぐだぐだ低レベルプログラミング(225)x86(16bit)、対数関数の計算 へ戻る

コメントを残す

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