有没有一种好方法可以将常量作为“参数”提供给内联汇编代码? 我正在尝试制作协处理器访问功能。 我尝试了两种方法:宏替换和扩展。
使用方法是这样的:
unsigned int read_ID_PFR1()
{
READ_CP15(0, 0, 1, 1);
return cp_reg_val;
}
宏观方法:
#define READ_CP15(opc, crn, crm, opc2) \
asm volatile (\
"push {r0, r1}\n\t"\
"mrc p15, opc, r0, crn, crm, opc2\n\t"\
"ldr r1, =cp_reg_val\n\t"\
"str r0, [r1]\n\t"\
"pop {r0, r1}\n\t"\
)
我认为参数(opc,crn,...)没有扩展,因为它们是 在引号内使用。
扩展方法如下所示:
#define WRITE_CP15(opc, crn, crm, opc2) \
asm volatile (\
"push {r0, r1}\n\t"\
"ldr r1, =cp_reg_val\n\t"\
"ldr r0, [r1]\n\t"\
"mcr p15, %[op], r0, c%[rn], c%[rm], %[op2]\n\t"\
"pop {r0, r1}\n\t"\
::[op]"I"(opc), [rn]"I"(crn), [rm]"I"(crm), [op2]"I"(opc2):\
)
除了“#”标记之外,这似乎做得更好。 (c%[rn] 扩展为 c#0)
最佳答案
不要将push/pop放入内联asm中。这不仅意味着您在 asm 中编写了比应有的更多的垃圾;而且还意味着您在 asm 中编写了更多的垃圾。它还排除使用“m”类型输入/输出约束,因为有效地址可能是堆栈指针相关的。相反,使用类似的东西:
asm volatile ("mrc p15, opc, %0, crn, crm, opc2" : "=r"(cp_reg_val));
关于c - GCC 内联汇编常量 (ARM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30608826/