【发布时间】:2015-06-03 00:27:01
【问题描述】:
有没有一种好方法可以将常量作为“参数”提供给内联汇编代码? 我正在尝试制作协处理器访问功能。 我尝试了两种方法:宏替换和扩展。
用法是这样的:
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)
【问题讨论】:
-
我自己确实和
_BKPT在一起。您需要一个宏才能使用任何优化设置。有趣的旁注:如果不使用-O0,这也适用于内联函数。对于-O0,gcc 抱怨他可能无法解析常量。原因显然是在检查 asm 约束之前进行内联(我使用了 'i' IIRC)。
标签: c gcc inline-assembly