指令级的带符号数模

时间:2018-10-22 16:21:32

标签: c gcc assembly modulus

之前读过this关于gccclang有符号数字模量计算的不同实现的有趣讨论,这对我来说是一个问题(不是在讨论中讨论)。

为什么要执行此操作?

if(num % 2 == 1)

从此开始(在clanggcc上相似):

movl    %edi, %eax
shrl    $31, %eax
addl    %edi, %eax

为什么我们从((num >> 31) + num)开始?为什么要使用MSB并将其添加到数字中?这是哪里来的?

1 个答案:

答案 0 :(得分:2)

% 2的结果是负余数,除法向C舍去为0。& 1仅适用于正数。

因此,编译器生成的代码将符号位数字相加-实质上将负数加1,这样-1的最后一位具有0,然后-2拥有{{1 }}的最后一位,1又有了-3 ...然后我们将除最后一位之外的所有字符都屏蔽掉,并从结果中减去符号位,例如:

0

它的性能可能比movl %edi, %edx shrl $31, %edx leal (%rdi,%rdx), %eax andl $1, %eax subl %edx, %eax 指令略强。例如,在Core i7上,具有r32的IDIV的延迟时间为17-28,吞吐量为7-12,而在生成的代码中,所有其他这些代码的延迟均为〜1