【问题标题】:GNU assembly Inline: what do %1 and %0 mean?GNU 汇编内联:%1 和 %0 是什么意思?
【发布时间】:2015-12-27 14:25:00
【问题描述】:

我对 GNU 汇编内联非常陌生,我已经阅读了多篇文章,但仍然不完全理解发生了什么。据我了解:

movl %eax, %ebx\n\t 会将%eax 中的内容移动到ebx,但不会相互添加内容

addl %eax, %ebx\n\t 会将%eax 的内容与ebx 相加,并保持在最右边的寄存器中

addl %1, %0\n\t 这是我感到困惑的地方,我们是在加 1 和 0?为什么我们需要有%0

【问题讨论】:

  • 在 at&t 语法中,目的地是右边,所以“保持在最左边的寄存器”是错误的。 %0 和 %1 引用约束部分中列出的替代输入/输出操作数。您可能想阅读manual
  • @Jester 抱歉打错了,这就是我的意思。现在说得通了,如果我使用 %2,那将是第三个输入/输出操作数?
  • 是的。另请注意,您可以使用%[name] 形式的命名操作数以使代码更具可读性。
  • 您始终可以查看编译器输出,以确保您的 %number 占位符按照您预期的方式进行了替换。如果使用内联 asm,请确保在破坏标志(条件条件)时告诉编译器,并在 clobber 列表中使用“cc”条目。如果您在 asm 中编写独立函数并从 C 中调用它们,您将更轻松地学习 asm。(将原型放在 .hmain.c 中,但只在 .s 中定义函数文件。)。 gcc inline asm 比普通 asm 更难阅读/使用。尽可能使用内置函数(例如 popcnt 或 SSE)。
  • 第一个建议:'权威'语法在gcc manual。可以在lockless 文章中找到更好的解释和教程,其中包含真实示例、陷阱和正确使用。 @PeterCordes 的建议非常好。添加一些内联汇编,用-c -S 编译,然后查看汇编输出。对于简单的内联(扩展)asm,您可能不知道 ABI 就可以逃脱。

标签: gcc assembly x86 inline-assembly att


【解决方案1】:

整个 asm 内联块看起来像:

 asm [volatile] ( AssemblerTemplate
                      : OutputOperands
                      [ : InputOperands
                      [ : Clobbers ] ])

 asm [volatile] ( AssemblerTemplate
                      : OutputOperands)

AssemblerTemplate 中是您的汇编代码,而在 Output/InputOperands 中,您可以在 C 和 ASM 之间传递变量。

那么在 Asm 中,%0 指代作为 OutputOperand 或 InputOperand 传递的第一个变量,%1 指代第二个等。

例子:

 int32_t a = 10;
 int32_t b;
 asm volatile ("movl %1, %0" : "=r"(b) : "r"(a) : );

这个asm代码相当于“b = a;”

更详细的解释在这里:https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 2017-05-31
    • 2018-09-25
    • 1970-01-01
    相关资源
    最近更新 更多