将指针的地址加载到寄存器内联拇指组件中

问题描述 投票:0回答:1

我正在尝试使用内联拇指组件将地址从我的 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) );

我尝试过使用不同的约束字符,但我对汇编不够熟悉,无法取得任何进展,任何帮助将不胜感激。

谢谢。

c pointers inline-assembly cpu-registers thumb
1个回答
0
投票

"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/infoARM 内联汇编:退出系统调用并从内存中读取值,了解如何编译的示例。

GCC 手册 (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html) 明确指出,寄存器 asm 局部变量的only保证行为是选择指定的寄存器内联

asm
语句; 保证在任何其他时间使用该寄存器。

© www.soinside.com 2019 - 2024. All rights reserved.