帮助理解x86内联汇编中的DIV指令

时间:2010-12-27 19:03:28

标签: c gcc x86 inline-assembly division

在阅读GNU项目中的一些源代码时,我遇到了一些内联汇编:

__asm__ (
  "divq %4"
  : "=a" (q), "=d" (r)
  : "0" (n0), "1" (n1), "rm" (d)
);

此处变量qrn0n1d是64位整数。我知道足够多的装配来得到它的作用,但有一些我不确定的细节。

我的理解:

我们将RAX寄存器的内容除以d,将商置于q,并将余数放在r

我不明白

  1. 为什么有三个输入 这里?我们只需要输入一个 分红和除数,所以有什么用 可以有3个输入吗?
  2. 我不知道哪个输入是红利。更一般地说,我实际上没有看到任何东西 被加载到RAX寄存器, 那它怎么知道分什么呢?

2 个答案:

答案 0 :(得分:4)

在输入操作数规范中:

: "0" (n0), "1" (n1), "rm" (d)
由于输出规范,

寄存器“0”和“1”被强制为raxrdx

: "=a" (q), "=d" (r)

div指令系列需要RDX:RAX中的分子。除数可以在通用寄存器中(未使用 - 即,不是RAXRDX)或内存,由“rm”约束指定。寄存器RDXRAX和除数操作数组成3个输入。

因此,最终会执行除法:n1:n0 / d其中n1:n0是加载到rdx:rax的数量。

答案 1 :(得分:0)

正确地看到div系列适用于a的固定寄存器draxrdxdivqa寄存器从n0获取其输入,该输入别名为第0个寄存器,即an1是一个别名为d的虚拟输入,可能只是为了确保该寄存器不用于其他目的。