帮助理解 x86 内联汇编中的 DIV 指令
Posted
技术标签:
【中文标题】帮助理解 x86 内联汇编中的 DIV 指令【英文标题】:Help understanding DIV instruction in x86 inline assembly 【发布时间】:2010-12-27 19:03:28 【问题描述】:在阅读 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 寄存器中,
那么它是如何知道除以什么的呢?
【问题讨论】:
+1 个格式正确的问题。我喜欢“我明白的”和“我不明白的”部分。 【参考方案1】:在输入操作数规范中:
: "0" (n0), "1" (n1), "rm" (d)
由于输出规范,寄存器“0”和“1”被强制为rax
和rdx
:
: "=a" (q), "=d" (r)
而div
指令族需要RDX:RAX
中的分子。除数可以在通用寄存器(不以其他方式使用 - 即,不是RAX
或RDX
)或内存中,由“rm”约束指定。寄存器RDX
、RAX
和除数操作数构成了 3 个输入。
所以这将最终执行除法:n1:n0 / d
其中n1:n0
是加载到rdx:rax
中的数量。
【讨论】:
我是否正确理解这可用于将 128 位整数除以 64 位整数?我知道这对于 32 位寄存器版本是可能的,但从没想过它也适用于 64 位版本。 @Jens:没错。但请记住(如较小的操作数除法运算),如果商最终对于rax
目标寄存器来说太大,您将得到除法异常。
测试这种情况的快速方法是确保rdx
小于除数,在这种情况下除法是安全的。【参考方案2】:
当您正确观察到div
系列在固定寄存器a
和d
、rax
和rdx
上工作divq
。 a
寄存器从n0
获取输入,n0
别名为第 0 个寄存器,即a
。 n1
是一个别名为d
的虚拟输入,可能只是为了确保该寄存器不用于其他目的。
【讨论】:
以上是关于帮助理解 x86 内联汇编中的 DIV 指令的主要内容,如果未能解决你的问题,请参考以下文章