ARM - 检测乘法结果是否适合32位

时间:2017-01-21 01:56:35

标签: assembly arm

在我的汇编过程中,我需要将两个无符号的32位整数相乘,如果结果太大而无法拟合为32位整数,则返回错误。

所以我这样做:

muls r3, r1, r2    @ r1, r2
bcs multiply_error

不幸的是,这不能像我预期的那样工作 - 我认为如果结果太大会设置进位标志,但是当r1 = 1且r2 = 1时,进位标志也被设置(为什么?)。我也尝试检查溢出标志 - 事实证明它根本没有设置(至少在我尝试过的测试中:r1 = 1,r2 = 1且r1 = UINT_MAX,r2 = 2)。

在这种情况下标志如何工作?如果r1 * r2适合32位,如何检查?

2 个答案:

答案 0 :(得分:2)

根据MUL指令的ARM文档:

  
      
  • C标志设置为无意义值
  •   
  • V标志未更改
  •   

所以那里没有帮助。相反,您需要使用UMULL指令(或SMULL,如果您想要签名),它将两个32位值相乘,在两个寄存器中产生64位结果,然后测试上面的寄存器如果它不是零。

答案 1 :(得分:1)

如果硬件没有帮助,你可以从你已经知道的东西中思考一下。数字4是二进制0b100,它是功率0加零的两倍加上功率1的两倍加上功率2的两倍。我们最高有效位是功率2的2倍乘以13的功率最大值比特是2到3的功率。所以我们有2 ^ 2 *(2 ^ 3 + 2 ^ 2 + 2 ^ 0)分配(2 ^ 2 * 2 ^ 3)+(2 ^ 2 * 2 ^ 2)和所以,我们最重要的一点来自(2 ^ 2 * 2 ^ 3),另一个数学属性来自2 ^(2 + 3)或2 ^ 5。所以我们现在需要至少6位,当我们将所有这些东西放在一起时,存在添加msbit的可能性,这意味着我们需要7位来乘以3位数(最重要的非零) bit是2的2到4位数(msb是2到3的幂)。 3 + 4 = 7位。对于未签名,对于签名,您必须考虑最重要的零或最重要的一个等等...

或者只使用简单路径任何32位模式时间任何32位模式都需要64位结果才能溢出。

就特定指令集的检测而言,只需读取该指令的处理器供应商文档。