11

我注意到,unsigned int 和 int 共享相同的加法和减法指令。但是为整数除法和乘法提供 idivl / imull ,为 unsigned int 提供 divl / mull 。我可以知道这个的根本原因吗?

4

3 回答 3

10

乘法或除法时的结果会有所不同,具体取决于您的参数是有符号还是无符号。

这真的是二进制补码的魔力,它允许我们对有符号和无符号加减法使用相同的操作。这在其他表示中是不正确的——一个的补码和符号大小都使用与无符号算术不同的加法和减法算法。

例如,对于 32 位字,用-1表示0xffffffff。对此进行平方,您会得到签名和未签名版本的不同结果:

Signed: -1 * -1 = 1 = 0x00000000 00000001
Unsigned: 0xffffffff * 0xffffffff = 0xfffffffe 00000001

注意结果的低位字是一样的。在不给你高位的处理器上,只需要一条乘法指令。在 PPC 上,有 3 条乘法指令 - 一条用于低位,两条用于高位,具体取决于操作数是有符号还是无符号。

于 2012-11-18T13:25:45.390 回答
0

大多数微处理器使用移位和加法算法(或类似算法)实现乘法和除法。这当然需要单独处理操作数的符号。使用加减法
实现乘法和除法时不必担心关于符号,因此允许互换处理有符号和无符号整数值,它的效率要低得多,这可能就是为什么不使用它的原因。

我刚刚读到一些现代 CPU 交替使用Booth 编码方法,但该算法也意味着断言值的符号。

于 2012-11-18T13:00:19.860 回答
0

在 x86 符号存储在字的高位(如果将谈论整数和无符号整数) ADD 和 SUB 命令使用一种算法来进行有符号和无符号输入 - 它在两者中都得到正确的结果。

对于 MULL 和 DIV,这是行不通的。你应该“告诉”CPU你想要“使用”有符号或无符号的int。对于无符号使用 MULL 和 DIV。它只是操作文字 - 它很快。对于签名使用 MULL 和 IDIV。它将单词转换为绝对(正)值,为结果存储符号,然后进行操作。这比 MULL 和 DIV 慢。

于 2012-11-18T13:24:36.057 回答