ARM Cortex-M0+下GCC内联汇编lo寄存器约束适配咨询
ARM Cortex-M0+ GCC汇编约束解决方案
问题背景
我正尝试使用arm-none-eabi-gcc为ARM Cortex-M0+(STM32G030)编译以下代码:
asm("ldrb %0, [%1, %2] " : "=l" (v) : "l" (R.a+(o&~31)) , "g" (o&31));
其中变量o可能在编译时已知,也可能在运行时才确定(此时需使用约束"l",因为必须采用lo寄存器(r0-r7)以适配16位Thumb指令)。需要找到一种约束,强制GCC对运行时未知值使用lo寄存器。
可行方案
方案1:直接使用"l"约束替代"g"
将第三个操作数的约束从"g"改为"l",这样无论o是编译期常量还是运行时变量,GCC都会将其分配到r0-r7范围的lo寄存器中。对于编译期已知的o&31,GCC会自动优化为立即数嵌入指令,不会产生额外开销,同时完全适配16位Thumb指令要求。
修改后的代码:
asm("ldrb %0, [%1, %2] " : "=l" (v) : "l" (R.a+(o&~31)) , "l" (o&31));
方案2:使用GCC扩展条件约束
如果需要更精细的控制,可利用GCC的条件约束语法,针对常量和变量分别指定规则:
asm("ldrb %0, [%1, %2] " : "=l" (v) : "l" (R.a+(o&~31)) , "i,l" (o&31));
这里"i,l"表示:若操作数是编译期常量,优先使用立即数(i约束);若为运行时变量,则强制分配lo寄存器(l约束),完美适配两种场景。
补充说明
ARM Cortex-M0+仅支持16位Thumb指令,ldrb的寄存器偏移版本要求偏移量必须是lo寄存器或5位立即数。上述两种方案均能确保运行时变量偏移量使用lo寄存器,同时不影响编译期常量的优化效果,完全适配STM32G030的指令集限制。
内容的提问来源于stack exchange,提问作者RRIDDICC
相关产品推荐
相关产品推荐

