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

发布于 2024-10-09 04:45:23 字数 577 浏览 3 评论 0原文

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

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

这里的变量 qrn0n1d 是 64 位整数。我对汇编有足够的了解,可以了解其作用的要点,但有一些细节我不确定。

我的理解:

我们将 RAX 寄存器的内容除以 d,将商放入 q,并将余数放入 <代码>r。

我不明白

  1. 为什么有三个输入 这里?我们只需要输入一个 被除数和除数有什么用 可以有3个输入吗?
  2. 我无法判断哪个输入是股息。更一般地说,我实际上什么也没看到 被加载到 RAX 寄存器中, 那么它怎么知道用什么除以什么呢?

While reading through some source code in a GNU project, I came across this bit of inline assembly:

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

Here the variables q, r, n0, n1, and d are 64-bit integers. I know enough assembly to get the gist of what this does, but there's some details I'm not certain about.

What I understand:

We're dividing the contents of the RAX register by d, placing the quotient in q, and placing the remainder in r.

What I don't understand

  1. Why are there three inputs
    here? We only need to input a
    dividend and a divisor, so what use
    could there be for 3 inputs?
  2. I can't tell which of the inputs is the dividend. More generally, I don't see anything actually
    being loaded into the RAX register,
    so how does it know what to divide by what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝咒 2024-10-16 04:45:23

在输入操作数规范中:

: "0" (n0), "1" (n1), "rm" (d)

由于输出规范,寄存器“0”和“1”被强制为 raxrdx

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

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

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

In the input operands specification:

: "0" (n0), "1" (n1), "rm" (d)

registers "0" and "1" are forced to rax and rdx because of the output specification:

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

And the div instruction family wants the numerator in RDX:RAX. The divisor can be in a general purpose register (not otherwise used - ie., not RAX or RDX) or memory, which is specified by the "rm" constraint. Registers RDX, RAX, and the divisor operand make up the 3 inputs.

So this will end up performing the division: n1:n0 / d where n1:n0 is a quantity loaded into rdx:rax.

月依秋水 2024-10-16 04:45:23

当您正确观察 div 系列在固定寄存器 adraxrdx 上工作时 代表divqa 寄存器从 n0 获取输入,该输入是第 0 个寄存器的别名,即 an1 是一个虚拟输入,别名为 d,可能只是为了确保该寄存器不用于其他目的。

As you correctly observe the div family works on the fixed registers a and d, rax and rdx for divq. The a register gets its input from n0 which is aliased to the 0th register, namely a. n1 is a dummy input aliased to d, probably just to ensure that this register is not used for other purposes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文