试图理解C中的内联汇编代码

时间:2017-06-07 21:32:13

标签: c gcc x86-64 inline-assembly

所以我有一些代码

#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位数相乘,即w0u。然后,它将该乘法的结果存储在w0w1

我的主要问题是:

  1. 根据This GCC assembly guide on Simple Constraints' a'并且' d' in "=a""=d"分别是地址和数据寄存器。这是怎么发挥的?这究竟是什么意思?
  2. "0"在这种情况下的含义是什么?同一指南说"允许匹配指定操作数的操作数。"这里匹配的操作数是什么?
  3. v如何发挥作用?如果有的话?
  4. 在函数调用结果之前和之后打印出变量

      

    w1 w0 u v

         

    2097147 549755813889 17179869183 4611684961865433149

         

    4294966311 17179869183 13835060159816138691 4611684961865433149

1 个答案:

答案 0 :(得分:3)

  1. mulq指令隐式生成ad个寄存器中的结果(通常称为raxrdx
  2. 操作数从零开始索引。因此,"0"表示与第一个操作数相同的位置,即w0mulq隐式使用rax作为输入操作数之一,因此匹配约束。可以再次将其写为"a"
  3. v是操作数%3,它是mulq指令中引用的唯一显式操作数。该代码会倍增uv,因此当然它会发挥作用"。
  4. 您在交换w0u的第二行上错误地打印了寄存器,因为uv是未更改的输入操作数。 u*v=w1*2^64+w0,即17179869183*4611684961865433149=4294966311*2^64+13835060159816138691