我需要在程序集中为32位AVR实现一小段代码(运行C程序下的内存测试测试RAM,没办法解决它),但我找不到AVR上的任何文档 - 内联汇编程序的32个细节,以及反复试验都没有让我获得成功。
第一件事:有没有人知道任何描述内联ASM的AVR-32细节的文档? (特别是输入/输出寄存器规范)
我设法达到了能够使用自动输入/输出寄存器分配编写内联片段的程度,但是奇怪的行为阻止我完成它。采取以下代码片段:
int ret;
int ad0;
int ad1;
/* ... */
__asm__ volatile(
"mov r2, %0 \n\t"
"mov r3, %1 \n\t"
"mov %2, 0 \n\t"
: "=r"(ret)
: "r"(ad0), "r"(ad1)
: "r2", "r3"
);
使用avr32-gcc进行优化编译后,它会生成以下程序集输出(-S
):
#APP
# 95 "svramt.c" 1
mov r2, r8
mov r3, r8
mov r9, 0
# 0 "" 2
#NO_APP
注意%0和%1如何映射到同一个寄存器(r8)。如果存在输出寄存器,这似乎就会发生。为了检查我是否在这里不正确地使用了内联汇编,我还在主机上尝试了使用本机gcc的X86:
int ret;
int ad0;
int ad1;
/* ... */
__asm__ volatile(
"mov %0, %%eax \n\t"
"mov %1, %%ebx \n\t"
"mov 0, %2, \n\t"
: "=r"(ret)
: "r"(ad0), "r"(ad1)
: "eax", "ebx"
);
此片段编译为:
#APP
# 7 "asmtest.c" 1
mov %esi, %eax
mov %edx, %ebx
mov 0, %ecx,
# 0 "" 2
#NO_APP
这是我期望AVR-32对应的,所有输入和输出映射到不同的寄存器。
我本来希望通过直接指定寄存器(尝试“= r8”和输入/输出规格)解决问题(如果它是avr32-gcc中的错误),但它不会编译方式。
如果没有文档,是否有人知道在(“普通”x86或ARM)GCC的源代码中可以找到内联asm的寄存器规范?值得一试,但海湾合作委员会是一个在没有任何先验知识的情况下跋涉的巨大野兽。
我不相信我有足够的业力来完成ASM模块(对AVR-32汇编知之甚少),这至少需要调用约定的文档,我也没有找到远...
编辑:进一步的实验表明,使用=&r
作为输出说明符似乎解决了寄存器映射问题。为什么这样,我无能为力(两个输入映射到同一个寄存器)。至少可以测试这个东西,因为它现在产生了预期的装配片段。
进一步的研究揭示了this AVR 8 bit document,它提供了解决方案的一部分,它通过描述方括号来提供操作数的名称,这些名称可以在汇编片段中使用。这消除了操作数将映射到片段中的%n
规范之间可能存在的模糊性。 (我看不到其他文档中描述的这种语法,但也适用于avr32-gcc,所以很有用)