私はコンピュータ サイエンスを専攻しており、アセンブリ言語が整数除算関数を処理する方法に興味があります。除算と mod の両方を与えながら、単純に分子に加算するのは非現実的であるように思われるので、ビット シフト、減算、および 2 つのルックアップ テーブルを使用して除算する別の方法を考え出しました。
基本的に、関数は分母を取り、2 の最大乗数に基づいて「ブロック」を作成します。したがって、15 で割ると 4 のバイナリ ブロックが作成され、5 で割ると 3 のバイナリ ブロックが作成されます。次に、最初の 2^block- を生成します。サイズは分母の倍数。倍数ごとに、最初のブロックの値をキーにして、最初のブロックの後に値をルックアップ テーブルに書き込みます。
例: 2 進数の 5 の倍数 - ブロック サイズ 3 (8 進数)
000 000 **101** - 5 maps to 0
000 001 **010** - 2 maps to 1
000 001 **111** - 7 maps to 1
000 010 **100** - 4 maps to 2
000 011 **001** - 1 maps to 3
000 011 **110** - 6 maps to 3
000 100 **011** - 3 maps to 4
000 101 **000** - 0 maps to 5
したがって、実際の手順には、最初のブロックを取得し、最初のブロックを左にビットシフトし、ブロックがマップする値を減算することが含まれます。結果の数値が 0 になる場合は完全に割り切れ、値が負になる場合はそうではありません。
別の列挙ルックアップ テーブルを追加すると、値が入ったときにカウンターにマップされ、除算の結果を計算できます。
例: 再び 5 の倍数
5 maps to 1
2 maps to 2
7 maps to 3
4 maps to 4
1 maps to 5
6 maps to 6
3 maps to 7
0 maps to 8
あとは、すべてのブロックをカウンター テーブルにマッピングするだけで、答えが得られます。
この方法にはいくつかの問題があります。
- 答えが完全に割り切れない場合、関数はジャンクを返します。
- 整数値が大きい場合、これは機能しません。これは、32 ビットまたは 64 ビット整数の最後で 5 ブロック サイズが切り捨てられるためです。
- C の標準除算よりも約 100 倍遅いです。
- 分母が除数の因数である場合、ブロックは複数の値にマップする必要があり、さらに多くのテーブルが必要になります。これは素因数分解で解決できますが、簡単/迅速な素因数分解について私が読んだすべての方法には、除算が含まれており、この目的を無効にしています。
質問が 2 つあります。まず、これに似たアルゴリズムは既に存在しますか? 辺りを見回しましたが、似たようなものは見当たらないようです。第二に、実際のアセンブリ言語は整数除算をどのように処理しますか?
スタック オーバーフローに投稿するのはこれが初めてです。