ARMv4 GCC环境下如何创建带多变量寄存器偏移的内联汇编指令?
解决ARMv4 GCC内联汇编的立即数运算语法错误问题
核心原因是GCC对"i"约束的立即数会自动添加#前缀,当在汇编模板中对多个这类占位符做运算时,每个占位符都会带上#,导致生成的代码违反ARM寻址语法(ARM基址偏移表达式中仅第一个立即数需要#,后续运算数无需前缀)。
正确实现方式
直接在C侧预先计算好完整的偏移值,作为单个立即数传入内联汇编,避免模板中出现多立即数运算:
asm("strb.w r2, [r0, %[offset]]" :: [offset] "i" (24 + 8 * 1) );
生成的正确汇编代码为:
strb.w r2, [r0, #32]
如果需要保留参数可读性(比如将offset、delta、scale作为独立变量),可先在C代码中计算总偏移:
const int offset = 24; const int delta = 8; const int scale = 1; const int total_offset = offset + delta * scale; asm("strb.w r2, [r0, %[total]]" :: [total] "i" (total_offset) );
原写法错误原因
原代码中每个"i"约束的参数都会被GCC转换为带#的立即数,导致模板中的%[offset] + %[delta] * %[scale]被展开为#24 + #8 * #1,不符合ARM汇编语法规则,因此报错。
内容的提问来源于stack exchange,提问作者Hansel
相关产品推荐
相关产品推荐

