c++ - 为什么在进行 int/unsigned int 除法时使用 'divl'

标签 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

你能告诉我,为什么 int 和 unsigned int 之间的划分使用 divl 而不是 idivl 吗?

最佳答案

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

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

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

关于c++ - 为什么在进行 int/unsigned int 除法时使用 'divl',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13439948/

相关文章:

c++ - 如何在 lambda 的 lambda 函数中捕获 "this"?

c - 本地测试 TCP/IP 服务器

assembly - 远跳到保护模式后的 GPF

c - 代码中的函数会使速度变慢吗?

c - malloc结构C

c - 汉明重量(数字中1的个数)混合C与组件

c++ - 是否有一个标准函数可以打印/监视标准输入文件的内容,同时将数据留在标准输入中?

c++ - gcc如何静态分配运行时已知长度的数组

c++ - 带有带有dlopen的共享库的不同数学符号绑定(bind),并直接链接到可执行文件(Linux)

当缓冲区为 1MB 时调用系统 ("printf buffer > output.txt") 写入文件失败