【问题标题】:error: unknown register name 'r3' in 'asm' , in clobber错误:“asm”中的未知寄存器名称“r3”,在clobber中
【发布时间】:2019-08-01 18:40:05
【问题描述】:

我想写一个内联汇编函数,它会做乘法和移位,然后将结果转换为 32 位值,我需要它但不能使用任何,产生错误

我想用clobbers进行计算,然后返回结果

    static inline int32_t multi(int32_t in0, int32_t in1)
{
    int32_t res=0;
    asm volatile ( "add.n r3 , %1 ,%1\n"
           "mull %0, %2 , r3\n"
           :"=r"(res) 
           : "r"(in0), "r"(in1)
               :"cc","r3");  
     return res;

}

它正在产生以下错误,

错误:“asm”中的未知寄存器名称“r3”

我尝试了很多寄存器,如 a1 a2 等,但似乎没有任何效果,我在上面的代码中是否犯了一些愚蠢的错误

【问题讨论】:

  • 您为哪种架构编程?
  • 请注意,编译器可能非常有能力从简单的 C 代码生成算术指令。确保它不是过早的优化。
  • 我不认识这里的拱门,但我想知道你是否可以这样做:"add.n %0 , %1 ,%1\n mull %0, %2 , %0\n"?使用更少的寄存器,并且不需要clobber。
  • 我没有找到专门为此的文档,但我发现的一些 xtensa 示例使用以“a”开头的寄存器名称(即 a3)。如果做不到这一点,请尝试在您的 2 个 asm 行前加上注释标记,然后使用 -S 编译以查看为 %0、%1 等生成的汇编程序。
  • 嗯,好吧,你去。总结一下,我应该提一下,(正确地)使用内联 asm 真的很难,通常是bad idea。是的,它很强大,是的,它具有教育意义,但对于生产代码来说几乎总是一个坏主意。

标签: c assembly inline-assembly


【解决方案1】:

我不确定“add.n”是什么。但从描述中,我猜你可能想要以下内容:

#include "stdio.h"
#include "stdint.h"

static inline int32_t multi(int32_t in0, int32_t in1)
{
        asm volatile (  "mul %1 \t\n"
                        :"+a"(in0), "+c"(in1)
                        :
                        :"memory");
        return in0;

}

void main() {
        int32_t a, b;

        //test data
        a = 2;
        b = 7;

        printf("result: %d\n", multi(a,b));
}

【讨论】:

  • 此代码是否适用于 x86? OP 使用不同的硬件(xtensa),它使用不同的constraints(即没有c)。
  • 即使这是针对 x86 的,也是不安全的:您在 "+a" (EAX) 中正确指定了输入/低半输出,但您忘记告诉编译器 1-operand @987654325 @ 用上半部分破坏 EDX。 (1-操作数mul 的效率低于imul,如果您不想要高半部分,则无论如何都不应该使用。)此外,您不需要或不想要volatile"memory" clobber , 而in1 不需要在 ECX 中。它也没有被修改,所以只输入"r"(in1) 会更有意义。如果您使用mull 强制操作数大小,或者"r,m" 允许内存。
猜你喜欢
  • 2014-12-08
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 2023-03-11
相关资源
最近更新 更多