我尝试使用内联thumb汇编从我的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) );
我已经尝试使用不同的约束字符,但我不熟悉的汇编取得任何进展,任何帮助将不胜感激。
谢谢.
1条答案
按热度按时间vsikbqxv1#
"i"(CurrentTaskStackPtr)
请求C变量的 value 作为立即数。只有当C变量是编译时常量时才能工作,如uint32_t *const CurrentTaskStackPtr = ...
。但是你的变量是volatile
(与指向volatile
分开),所以即使启用了优化,你也禁止编译器通过赋值进行常量传播来生成"i"(0x20000001)
。如果您想要地址,请使用地址
"i"(&CurrentTaskStackPtr)
。或者更好的方法是,让编译器在R8中为您提供地址,而不是将
ldr
伪指令放入asm模板中,除非您需要控制它如何实现地址或其他内容。另请参阅https://stackoverflow.com/tags/inline-assembly/info和ARM内联asm:exit system call with value read from memory for an example of how this compiles.
GCC手册(https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html)明确指出,寄存器asm局部变量的 * 唯一 * 保证行为是为内联
asm
语句选择指定的寄存器;它 * 不 * 保证在任何其他时间使用该寄存器。另请参阅How can I indicate that the memory pointed to by an inline ASM argument may be used?了解更多关于为什么
"memory"
clobber是必要的。可能最好使用它来代替虚拟输入/输出操作数;你也不希望编译器试图围绕上下文切换进行优化。尝试进行上下文切换
您可能更适合将上下文切换函数编写为
__attribute__((naked))
,这样就不必担心编译器何时访问相对于堆栈指针的局部变量。官方不支持在asm
语句中更改堆栈指针。(https:gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#index-asm-clobbers-clobber列表不应包含堆栈指针。)除了在
naked
函数中,你在Basic Asm语句中编写整个函数的asm,它不能内联到任何调用者中,因为它就像__attribute__((noinline,noipa))
,或者像在单独的.s
文件中编写它,只是定义一个原型。