帮助理解 x86 内联汇编中的 DIV 指令
在阅读 GNU 项目中的一些源代码时,我遇到了这段内联汇编:
__asm__ (
"divq %4"
: "=a" (q), "=d" (r)
: "0" (n0), "1" (n1), "rm" (d)
);
这里的变量 q
、r
、n0
、 n1
和 d
是 64 位整数。我对汇编有足够的了解,可以了解其作用的要点,但有一些细节我不确定。
我的理解:
我们将 RAX 寄存器的内容除以 d
,将商放入 q
,并将余数放入 <代码>r。
我不明白
- 为什么有三个输入 这里?我们只需要输入一个 被除数和除数有什么用 可以有3个输入吗?
- 我无法判断哪个输入是股息。更一般地说,我实际上什么也没看到 被加载到 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
- 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? - 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在输入操作数规范中:
由于输出规范,寄存器“0”和“1”被强制为
rax
和rdx
:以及
div
指令系列需要RDX:RAX
中的分子。除数可以位于通用寄存器(不以其他方式使用 - 即不是RAX
或RDX
)或内存中,由“rm”约束指定。寄存器 RDX、RAX 和除数操作数组成了 3 个输入。因此,这最终将执行除法:
n1:n0 / d
,其中n1:n0
是加载到rdx:rax
中的数量。In the input operands specification:
registers "0" and "1" are forced to
rax
andrdx
because of the output specification:And the
div
instruction family wants the numerator inRDX:RAX
. The divisor can be in a general purpose register (not otherwise used - ie., notRAX
orRDX
) or memory, which is specified by the "rm" constraint. RegistersRDX
,RAX
, and the divisor operand make up the 3 inputs.So this will end up performing the division:
n1:n0 / d
wheren1:n0
is a quantity loaded intordx:rax
.当您正确观察
div
系列在固定寄存器a
和d
、rax
和rdx 上工作时
代表divq
。a
寄存器从n0
获取输入,该输入是第 0 个寄存器的别名,即a
。n1
是一个虚拟输入,别名为d
,可能只是为了确保该寄存器不用于其他目的。As you correctly observe the
div
family works on the fixed registersa
andd
,rax
andrdx
fordivq
. Thea
register gets its input fromn0
which is aliased to the 0th register, namelya
.n1
is a dummy input aliased tod
, probably just to ensure that this register is not used for other purposes.