为什么imul用于乘以无符号数?

时间:2017-03-03 20:10:17

标签: assembly x86 64-bit posix x86-64

我编写了以下程序:

 0: 89 f8                   mov    eax,edi
 2: 48 0f af c0             imul   rax,rax
 6: c3                      ret  

这反汇编:

imul

gcc是将签名数字相乘的说明。为什么uint64_t使用它呢?

/ edit:使用0: 48 0f af ff imul rdi,rdi 4: 48 89 f8 mov rax,rdi 7: c3 ret 时,程序集类似:

expr

1 个答案:

答案 0 :(得分:0)

#include <stdint.h>

uint64_t fun0 ( uint32_t x )
{
    return (uint64_t)x * (uint64_t)x;
}
uint64_t fun1 ( uint32_t x )
{
    return ((uint64_t)x) * ((uint64_t)x);
}
uint64_t fun2 ( uint64_t x )
{
    return (x * x);
}



0000000000000000 <fun0>:
   0:   89 f8                   mov    %edi,%eax
   2:   48 0f af c0             imul   %rax,%rax
   6:   c3                      retq   
   7:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
   e:   00 00 

0000000000000010 <fun1>:
  10:   89 f8                   mov    %edi,%eax
  12:   48 0f af c0             imul   %rax,%rax
  16:   c3                      retq   
  17:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
  1e:   00 00 

0000000000000020 <fun2>:
  20:   48 89 f8                mov    %rdi,%rax
  23:   48 0f af c7             imul   %rdi,%rax
  27:   c3                      retq   

修改

即使您指定所有64位无符号,它也会生成相同的结果

0x00FF * 0x00FF = 0xFE01
0xFFFF * 0xFFFF = 0xFFFE0001
so
0xFF * 0xFF = 0x01

符号扩展对于低64位无关紧要,因此您可以将imul用于8,16,32和64位操作数的有符号或无符号。