我正在尝试使用内联拇指组件将地址从我的 c 指针读入寄存器。
这是一个可重现的:
static uint32_t volatile * volatile CurrentTaskStackPtr;
CurrentTaskStackPtr = (uint32_t *) 0x20000001;
__asm volatile("LDR R8, =%0" : : "i"(CurrentTaskStackPtr) );
此外,我试图避免更改任何“上下文”寄存器的状态,这就是我使用立即读取的原因。
我不断收到此错误:
warning: 'asm' operand 0 probably does not match constraints
187 | __asm volatile("LDR R8, =%0" : : "i"(CurrentTaskStackPtr) );
我尝试过使用不同的约束字符,但我对汇编不够熟悉,无法取得任何进展,任何帮助将不胜感激。
谢谢。
"i"(CurrentTaskStackPtr)
要求 C 变量的 value 作为立即数。仅当 C 变量是编译时常量(如 uint32_t *const CurrentTaskStackPtr = ...
)时,这才有效。但你的变量是 volatile
(与指向 volatile
分开),所以即使启用了优化,你也禁止编译器通过赋值进行常量传播以生成 "i"(0x20000001)
。
想要地址就拿地址吧,
"i"(&CurrentTaskStackPtr)
。
或者更好的是,要求编译器为您提供 R8 中的地址,而不是将
ldr
伪指令放入您的 asm 模板中,除非您需要控制它如何实现地址或其他内容。
register void *tmp_r8 asm("r8"); // forces "r" constraints to pick R8.
tmp_r8 = &CurrentTaskStackPtr;
asm("..."
: // outputs
: "r"(tmp_r8)
: "memory" // presumably you're going to deref that pointer
);
另请参阅 https://stackoverflow.com/tags/inline-assemble/info 和 ARM 内联汇编:退出系统调用并从内存中读取值,了解如何编译的示例。
GCC 手册 (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html) 明确指出,寄存器 asm 局部变量的only保证行为是选择指定的寄存器内联
asm
语句; 不保证在任何其他时间使用该寄存器。