为什么在执行 int / 无符号 int 除法时使用 'divl'

Why using 'divl' when doing int / unsigned int division

本文关键字:int divl 除法 执行 无符号 为什么      更新时间:2023-10-16

我在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 和无符号 int 吗?

由于ac的类型具有相同的转换等级,但a是有符号的,c是无符号的,因此a在除法之前转换为unsigned int,在a / cc / a中。

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

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