我注意到,unsigned int和int共享相同的加法和减法指令。但是为整数除法和mutiply提供idivl / imull,为unsigned int提供divl / mull。我可以知道这个的根本原因吗?
答案 0 :(得分:10)
根据您的参数是有符号还是无符号,结果会有所不同。
这是两个补码的神奇之处,它允许我们对有符号和无符号加法和减法使用相同的操作。在其他表示中不是这样 - 补语和符号幅度都使用与无符号算法不同的加法和减法算法。
例如,对于32位字,-1
由0xffffffff
表示。对此进行平方,对于有符号和无符号版本,您会得到不同的结果:
Signed: -1 * -1 = 1 = 0x00000000 00000001
Unsigned: 0xffffffff * 0xffffffff = 0xfffffffe 00000001
请注意,结果的低位字是相同的。在没有给出高位的处理器上,只需要一个乘法指令。在PPC上,有三个乘法指令 - 一个用于低位,两个用于高位,具体取决于操作数是有符号还是无符号。
答案 1 :(得分:0)
大多数微处理器使用shift-and-add algorithm(或类似的算法)实现乘法和除法。这当然要求操作数的符号单独处理。
虽然使用add-an-substract实现乘法和除法可以让人不用担心符号,因此可以互换地处理有符号整数和无符号整数值,但它的效率要低得多,而这可能就是它没有被使用的原因。
我刚刚读到一些现代CPU使用Booth encoding方法,但该算法也暗示断言值的符号。
答案 2 :(得分:0)
在x86符号存储中高位字(如果会谈论整数和无符号整数) ADD和SUB命令使用一种算法进行有符号和无符号输入 - 它在两者中得到正确的结果。
对于MULL和DIV,这不起作用。你应该“告诉”CPU你想要“使用”签名或未签名的int。 对于未签名使用MULL和DIV。它只是操作文字 - 它很快。 签名使用MULL和IDIV。它得到绝对(正)值,存储结果符号然后进行操作。这比MULL和DIV慢。