4

我是计算机科学专业的,对汇编语言如何处理整数除法函数感兴趣。似乎简单地将分子相加,同时给出除法和模数,太不切实际了,所以我想出了另一种使用位移、减法和 2 查找表来进行除法的方法。

基本上,该函数取分母,并根据 2 的最高幂生成“块”。因此,除以 15 得到 4 的二进制块,除以 5 得到 3 的二进制块,依此类推。然后生成第一个 2^block- size 分母的倍数。对于每个倍数,将第一个块之后的值写入查找表,以第一个块的值为键。

示例:二进制 5 的倍数 - 块大小 3(八进制)

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  

然后剩下的就是将每个块映射到计数器表,你就有了答案。
这种方法存在一些问题。

  1. 如果答案不是完全可分的,则该函数返回垃圾。
  2. 对于高整数值,这将不起作用,因为 5 块大小将在 32 位或 64 位整数的末尾被截断。
  3. 它比 C 中的标准除法慢大约 100 倍。
  4. 如果分母是除数的一个因素,那么您的块必须映射到多个值,并且您需要更多的表。这可以通过素数分解来解决,但我读过的所有关于简单/快速素数分解的方法都涉及除法,违背了这个目的。

所以我有两个问题:首先,是否已经有类似的算法?我环顾四周,似乎找不到任何类似的东西。其次,实际的汇编语言如何处理整数除法?

抱歉,如果有任何格式错误,这是我第一次发布堆栈溢出。

4

1 回答 1

1

抱歉这么晚才回复。好的,首先关于您问题的评论者:他们认为您正在尝试通过在 assembly 中使用不同的指令来完成程序集 memonic DIV 或 IDIV 所实现的目标。对我来说,您似乎想知道 DIV 和 IDIV 选择的操作码如何实现硬件划分。据我所知,英特尔使用 SRT 算法(使用查找表),而 AMD 使用 Goldschmidt 算法。我认为您所做的与 SRT 类似。您可以在这里查看它们:

http://en.wikipedia.org/wiki/Division_%28digital%29

于 2011-02-21T11:02:47.127 回答