我注意到,无符号整数和有符号整数在加减操作时使用相同的指令。但是在整数除法和乘法方面,有符号整数提供了idivl/imull,而无符号整数提供了divl/mull。请问这其中的原因是什么?
当您进行乘法或除法运算时,结果会因参数是有符号还是无符号而有所不同。
正是二进制补码的魔力使我们能够使用相同的操作符进行有符号和无符号的加减运算。这在其他表示方法中并不成立——反码和补码都使用与无符号算术不同的加减算法。
例如,在32位字中,-1
由0xffffffff
表示。对其进行平方,有符号和无符号版本会得到不同的结果:
Signed: -1 * -1 = 1 = 0x00000000 00000001
Unsigned: 0xffffffff * 0xffffffff = 0xfffffffe 00000001
请注意结果的低位是相同的。在那些没有给出高位的处理器上,只需要一条乘法指令。在 PPC 上,有三个乘法指令——一个用于低位,另外两个用于高位,具体取决于操作数是否带符号。
imul
仅提供低位字。 - haroldpclmulqdq
,所以我认为它不算是imul
的一个版本。 - haroldand
。 - Dietrich Epp0xffffffff ÷ 2
等于多少?对于有符号数 ((-1) ÷ 2
) 和无符号数 (0xffffffff ÷ 2
),答案是否不同? - Dietrich Epp在x86中,如果我们谈论整数和无符号整数,符号存储在字的高位。 ADD和SUB命令使用一种算法来处理有符号和无符号的情况,可以得到正确的结果。
但是对于MULL和DIV,这种方法不适用。您需要“告诉”CPU您想要“使用”有符号或无符号的int。 对于无符号,请使用MULL和DIV。它只操作字 - 这很快。 对于有符号,请使用MULL和IDIV。它将字转换为绝对(正)值,将符号存储为结果,然后执行操作。这比MULL和DIV慢。