Hyfaxのこと-整数が足りない(2)

x86リアルモードでモニターを作ろうシリーズです。Windows11+wsl2で構築しています。

前回は BCD ライブラリを「導入しただけ」で終わりました。
おなか一杯とか言って終わりにしました。

……が、さすがに導入だけで終わると「で、何ができるの?」というお話になるので、今回は 計算のコア をやります。

やることは単純で、

  • PHS(packed) ⇄ DHS(unpacked)
  • 計算は DHS で筆算
  • 最後に PHS に戻す

という流れ。前回の変換関数(pack/unpack)はそのまま使います。


方針:符号つき四則演算は “絶対値” に落として処理する

BCD筆算は「桁列」を扱うので、符号まで混ぜると面倒になります。
なので基本方針はこれ。

  1. 符号だけ先に剥がす(signを別に持つ)
  2. 絶対値で add/sub/mul/div
  3. 最後に 符号を付け直す

これをやるだけで、気持ちがだいぶ楽になります。


まずは比較:cmp_abs(絶対値比較)

加減算は「どっちが大きい?」がないと破綻します。
DHS は 下位桁が index 0 の “リトルエンディアン桁列” として扱うことにします(0桁目が1の位)。


絶対値加算:add_abs(桁上がりだけ)

これは筆算なので素直です。
A+B を計算して、carry を次桁へ。


絶対値減算:sub_abs(借りだけ)

A-B(ただし |A|>=|B| を前提)です。


ここで “符号つき add/sub” を組む

符号の組み合わせは結局こうです。

  • same sign:絶対値加算、符号はそのまま
  • different sign:大きい方から小さい方を引いて、符号は“大きい方”

これで 符号付き加算 ができます。

(この辺は “書くのは面倒だけど考え方は小学生とか中学生なので、コードの全体は github に置くことにします)


乗算:まずは「1桁 × 多桁」(mul_digit)

いきなり多桁×多桁をやると泣くので、最初はこれ。

  • C = A * digit(0..9)

この mul_digit ができると、次は「筆算の掛け算」がそのまま書けます。
(つまり “各桁の mul_digit をずらしながら足す”)


除算:今回は 割り算の入口だけ(div_digit)

本当は除算まで行きたいところですが、除算は一気に面倒になります。
なので今回は入口として、

  • A ÷ digit(0..9)で 商と余り

を作って終わります。
これがあると「10進→2進」「2進→10進」の補助にも使えて便利です。
上位桁から順に余りを *10 倍して足し、割り算を行う筆算そのままの流れで商を構築します。


実行できること

この段階でできることは、

  • 符号つき加算/減算(PHS)
  • 1桁乗算(DHS)
  • 1桁除算(DHS)

です。

「64bitが欲しい」から始まったのに、気づいたら 10進20桁 を手に入れつつあります。
現代の感覚だと遠回りすぎますが、リアルモードだとこれが近道です。たぶん。


そんなこんなで

まだ “おなか一杯” にはなってません。
むしろ、ここからが地獄です。

次回は多分、

  • 多桁×多桁(筆算の掛け算)
  • 正規化の地獄(len と leading zero)
  • そして、みんな大好き「ゼロの符号問題」

あたりをやります。やる……はず。

今回はここまでです。お付き合いいただきありがとうございました。

《2026/1/13 12:32:06》

コメントを残す

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