内联Thumb汇编中将C指针地址加载到寄存器的问题求助
解决内联Thumb汇编加载指针地址的警告问题
问题根源
你用的"i"约束要求操作数是编译期就能确定的立即数,但CurrentTaskStackPtr是运行时赋值的变量——它的内存地址虽编译期确定,但存储的内容(即你赋值的0x20000001)是运行时才固定的,完全不符合"i"约束的要求,这就是警告的核心原因。
针对不同需求的解决方案
需求1:把CurrentTaskStackPtr的值(即0x20000001)加载到R8
这个值存在变量的内存空间里,需要从内存读取,用"m"约束表示操作数是内存地址,配合直接内存加载指令:
__asm volatile("LDR R8, [%0]" : : "m"(CurrentTaskStackPtr) );
需求2:把CurrentTaskStackPtr变量自身的地址加载到R8
如果目标是获取变量本身的内存地址(而非它存储的值),可以用"p"约束(专门适配编译期可确定的指针/内存地址),配合LDR =伪指令:
__asm volatile("LDR R8, =%0" : : "p"(CurrentTaskStackPtr) );
额外注意事项
- Thumb模式下,
LDR Rn, =imm是编译器伪指令,会自动判断imm是否符合Thumb立即数规则:符合则生成MOV指令直接加载,不符合则生成从文字池加载的指令,无需手动处理。 - 若要严格保证上下文不被破坏,记得在使用R8前压栈保存,使用完成后弹栈恢复:
__asm volatile( "PUSH {R8}\n" // 保存R8到栈 "LDR R8, [%0]\n" // 加载变量值到R8 // 这里添加你需要用R8执行的操作 "POP {R8}\n" // 恢复R8原有值 : : "m"(CurrentTaskStackPtr) : "memory" );
内容的提问来源于stack exchange,提问作者Chimess
相关产品推荐
相关产品推荐

