内存操作数如何在avr-gcc内联汇编中工作?

时间:2013-06-29 00:16:42

标签: gcc assembly inline-assembly memcpy avr

我正在尝试为AVR编写自定义内存复制函数作为内联汇编,因为avr-gcc将始终使用循环进行memcpy和struct赋值,这在时间上是低效的。我想使用内存操作数来避免添加“内存”clobber。我目前有这个:

void copy_2_bytes (char *restrict dst, char *restrict src)
{
    struct S {
        char x[2];
    };
    __asm__(
        "    ld __tmp_reg__,%[src]+\n"
        "    st %[dst]+,__tmp_reg__\n"
        "    ld __tmp_reg__,%[src]+\n"
        "    st %[dst]+,__tmp_reg__\n"
        : [dst] "=m" ( *(struct S *)dst )
        : [src] "m" ( *(struct S *)src )
    );
}

这是编译,但一般来说它是不正确的,因为它修改了与内存操作数对应的指针寄存器对。很容易看出gcc假设寄存器保持不变,例如通过添加“* dst = 0;”集会后。

另一方面,Y和Z寄存器支持“ldd”和“std”指令,这些指令也采用立即偏移,因此它们可用于访问多个字节而无需修改。但是,似乎没有办法迫使gcc不选择X寄存器,这不支持。

更新

实际上,如果gcc确定内存操作数的地址是常量,它会将常量地址传递给程序集,而不是寄存器对。所以现在,我完全不知道如何处理这个问题。是否有一些魔术指令或汇编宏可以同时处理指针寄存器和常量地址?

0 个答案:

没有答案