如何解决为什么有些算术指令有有符号/无符号变体,而有些则没有
假设我们有:
a = 0b11111001;
b = 0b11110011;
如果我们用手在纸上做 Addition
和 Multiplication
,我们会得到这个结果,我们不在乎它是否签名:
a + b = 111101100
a * b = 1110110001011011
我知道乘法将宽度加倍,加法可能会溢出:
Why is imul used for multiplying unsigned numbers?
Why do some CPUs have different instructions to do signed and unsigned operations?
我的问题是,为什么像 Add
这样的指令通常没有签名/未签名版本,而 Multiply
和 Divide
有?
为什么我们不能有一个通用的 unsigned multiply
,像我上面做的那样做数学运算,如果它被烧毁,就截断结果,就像 Add
一样。
或者另一个,为什么 Add
不能有签名/未签名版本。我检查了一些架构,情况似乎是这样。
解决方法
我认为您选择的示例误导了您认为可以通过将 8x8 => 16 位无符号产品截断为 8 位来获得有符号产品。事实并非如此。
(249-256) * (243-256)
= 0x005b
,一个小的正结果恰好适合完整结果的下半部分。但是完整的有符号结果并不总是无符号乘积的操作数大小截断。
例如,-128 * 127
是 -16256
,或者作为 16 位 2 的补码,0xc080
。
但是 0x80 * 0x7f
是 + 16256,即 0x3f80
。相同的下半部,不同的上半部。
或者另一个例子,参见Why are signed and unsigned multiplication different instructions on x86(-64)?
扩大有符号乘法不涉及任何截断。有符号和无符号乘法的低半部分是相同的,这就是为什么例如 x86 只有立即数和 2 操作数形式的 imul
,而不是 mul
。只有扩大乘法需要一个单独的形式。 (或者,如果您想要 FLAGS set according to unsigned overflow of the low half,instead of signed overflow. - 因此,如果您想检测完整的未签名结果何时不适合,则无法轻松使用非扩展 imul
。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。