为什么在执行int / unsigned int除法时使用'divl'

时间:2012-11-18 12:06:56

标签: c++ c x86 unsigned-integer

我在X86中测试了这段代码。

void func()
{
  int a, b;
  unsigned int c, d;
  int ret;

  ret = a / b;  // This line use idivl, expected
  ret = c / d;  // this line use idivl, expected
  ret = a / c;  // this line use divl..., surprised 
  ret = c / a;  // this line use divl..., supriised
  ret = a * c;  // this line use imull, expected
}

我在这里粘贴汇编代码:

func:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $36, %esp
    movl    -4(%ebp), %eax
    movl    %eax, %edx
    sarl    $31, %edx
    idivl   -8(%ebp)
    movl    %eax, -20(%ebp)
    movl    -12(%ebp), %eax
    movl    $0, %edx
    divl    -16(%ebp)
    movl    %eax, -20(%ebp)
    movl    -4(%ebp), %eax
    movl    $0, %edx
    divl    -12(%ebp)
    movl    %eax, -20(%ebp)
    movl    -4(%ebp), %eax
    movl    %eax, -36(%ebp)
    movl    -12(%ebp), %eax
    movl    $0, %edx
    divl    -36(%ebp)
    movl    %eax, -20(%ebp)
    movl    -4(%ebp), %eax
    imull   -12(%ebp), %eax
    movl    %eax, -20(%ebp)
    leave
    ret

请您告诉我,为什么使用divl而不是idivl来区分int和unsigned int?

1 个答案:

答案 0 :(得分:6)

由于ac的类型具有相同的转换排名,但a已签名且c未签名,a将转换为{分割前{1}} unsigned inta / c

编译器因此针对这些情况发出无符号除法指令c / a(以及div,其中两个操作数都是无符号的)。

乘法c / d也是无符号乘法。在这种情况下,编译器可以使用带符号的乘法指令a * c,因为无论是使用imull还是mull,截断的结果都是相同的 - 只有标志不同,并且生成的代码不会测试这些。