【问题标题】:Can I use output operand as an input inside ARM inline assembly?我可以在 ARM 内联汇编中使用输出操作数作为输入吗?
【发布时间】:2015-12-14 19:38:55
【问题描述】:

我有一个包含两行小行的内联汇编代码。我想使用从第一行检索到的输出操作数作为第二行的输入操作数。我想知道这是否可能。这是我的代码:

asm volatile(   "umull          %0, %1, %3, %4; \n\t"
                "adds           %2, %5, %0;     \n\t"
                :"=r"(mullo2), "=r"(mulhi2), "=r"(temp)
                :"r"(A), "r"(B->uint32[6]), "r"(mulhi1)
                :"cc");

正如您在此处看到的,我需要 mullo2 操作数作为我在第二条指令中的输入之一。编译器不会抱怨它,但不知何故我没有得到正确的结果。

【问题讨论】:

  • 是的,你可以。检查生成的 asm 代码(使用 gcc -Sobjdump)。还要说明您提供的输入和获得的输出以及不正确的原因。
  • 不确定我是否理解正确,但是:如果您在 same asm 语句中使用寄存器,则必须在 clobber 部分中列出它们,但不能作为输入或输出。否则,如果要更改输入参数,则必须将其输入/输出。请注意,使用uint32 作为名称是一个坏主意,因为它很容易与uint32_t 类型混淆。一般来说,使用不言自明的名称,而不是它们的类型。
  • 另请注意,输出操作数可能与输入分配到相同的寄存器,除非您使用 early-clobber。在您的情况下,%5 可能与 %0%1 相同,并且由于它们已被第一条指令破坏,因此您的第二条指令将使用错误的值。
  • 你应该考虑跳过任何内联 asm 的东西,只在 ASM 中编写整个方法。生成函数调用和返回逻辑的代码可以生成一次,然后用作 asm 的模板。尝试用 C 语言做一半逻辑,用 ASM 做一半逻辑的问题太多了,但它会变得可怕。从用 asm 编写整个函数的方法开始是更好的方法。
  • 另外,也许还可以考虑完全跳过汇编麻烦,在编写 C 时只考虑底层指令集,因为compilers can often do a damn good job if you feed them code they can understand the intention of

标签: c assembly arm inline-assembly


【解决方案1】:

输出操作数可能与输入分配到相同的寄存器,除非您使用 early-clobber。在您的情况下,%5 可能与%0%1 相同,并且由于它们被第一条指令破坏,因此您的第二条指令将使用错误的值。因此,您应该在这两个输出操作数上使用 early-clobber 修饰符,例如 "=&r"(mullo2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    相关资源
    最近更新 更多