试图理解 C 中的内联汇编代码
Trying to understand inline assembly code in C
所以我有一些代码
#define umul_ppmm(w1, w0, u, v) \
asm ("mulq %3" \
: "=a" (w0), "=d" (w1) \
: "0" ((uint64_t)(u)), "rm" ((uint64_t)(v)))
我正在尝试调试它并了解它是如何工作的。
目前,我正在查看 This pdf 以供参考 mulq
。
到目前为止,我的理解是它将两个 64 位数字相乘,即 w0
和 u
。然后它将乘法的结果存储在 w0
和 w1
.
中
我的主要问题是:
- 根据This GCC assembly guide on Simple Constraints 'a'和'd'在
"=a"
和"=d"
分别是地址和数据寄存器。这在这里是如何发挥作用的,这到底是什么意思?
- 在这种情况下,
"0"
是什么意思?同一指南说 "An operand that matches the specified operand number is allowed." 这里的匹配操作数是什么?
v
是如何发挥作用的?如果有的话?
打印出函数调用前后的变量结果
w1 w0 u v
2097147 549755813889 17179869183 4611684961865433149
4294966311 17179869183 13835060159816138691 4611684961865433149
mulq
指令隐式地在 a
和 d
寄存器中产生结果(通常称为 rax
和 rdx
)
- 操作数从零开始索引。
"0"
因此表示与第一个操作数相同的位置,即 w0
。 mulq
隐式使用 rax
作为输入操作数之一,因此是匹配约束。可以再写成 "a"
。
v
是操作数 %3
,它是 mulq
指令中唯一引用的显式操作数。代码乘以 u
和 v
所以当然是 "comes into play".
您打印的寄存器错误,在第二行您交换了 w0
和 u
,因为 u
和 v
是未更改的输入操作数。
u*v=w1*2^64+w0
,即17179869183*4611684961865433149=4294966311*2^64+13835060159816138691
所以我有一些代码
#define umul_ppmm(w1, w0, u, v) \
asm ("mulq %3" \
: "=a" (w0), "=d" (w1) \
: "0" ((uint64_t)(u)), "rm" ((uint64_t)(v)))
我正在尝试调试它并了解它是如何工作的。
目前,我正在查看 This pdf 以供参考 mulq
。
到目前为止,我的理解是它将两个 64 位数字相乘,即 w0
和 u
。然后它将乘法的结果存储在 w0
和 w1
.
我的主要问题是:
- 根据This GCC assembly guide on Simple Constraints 'a'和'd'在
"=a"
和"=d"
分别是地址和数据寄存器。这在这里是如何发挥作用的,这到底是什么意思? - 在这种情况下,
"0"
是什么意思?同一指南说 "An operand that matches the specified operand number is allowed." 这里的匹配操作数是什么? v
是如何发挥作用的?如果有的话?
打印出函数调用前后的变量结果
w1 w0 u v
2097147 549755813889 17179869183 4611684961865433149
4294966311 17179869183 13835060159816138691 4611684961865433149
mulq
指令隐式地在a
和d
寄存器中产生结果(通常称为rax
和rdx
)- 操作数从零开始索引。
"0"
因此表示与第一个操作数相同的位置,即w0
。mulq
隐式使用rax
作为输入操作数之一,因此是匹配约束。可以再写成"a"
。 v
是操作数%3
,它是mulq
指令中唯一引用的显式操作数。代码乘以u
和v
所以当然是 "comes into play".
您打印的寄存器错误,在第二行您交换了 w0
和 u
,因为 u
和 v
是未更改的输入操作数。
u*v=w1*2^64+w0
,即17179869183*4611684961865433149=4294966311*2^64+13835060159816138691