裸函数内部——如何做简单的赋值
inside naked function - how to do simple assignment
这是一个已经存在并且有效的函数的开始;注释行是我添加的,其目的是切换引脚。
inline __attribute__((naked))
void CScheduler::SwapToThread(void* pNew, void* pPrev)
{
//*(volatile DWORD*)0x400FF08C = (1 << 14);
if (pPrev != NULL)
{
if (pPrev == this) // Special case to save scheduler stack on startup
{
asm("mov lr,%0"::"p"(&CScheduler_Run_Exit)); // load r1 with schedulers End thread
asm("orr lr, 1");
当我取消注释添加时,我的硬故障处理程序将执行。我知道这与 naked
函数有关,但我不明白为什么简单的赋值会导致问题。
两个问题:
- 为什么这条线会触发硬故障?
- 如何在这个函数中执行这个赋值?
幸运的是你以前版本的功能碰巧没有崩溃。
唯一可以安全地放入 naked
函数中的是纯 Basic Asm 语句。 https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html。您可以将其拆分为多个 Basic Asm 语句,而不是 asm("insn \n\t"
/ "insn2 \n\t"
/ ...);
,但您必须自己在 asm 中编写整个函数。
While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
如果您想 运行 来自裸函数的 C++ 代码,您可以 call
常规函数(或者 bl
在 ARM 上,jal
在 MIPS 等.), 遵循标准调用约定。
请问本案的具体原因是什么?也许在寄存器中创建该地址会踩到函数参数,导致分支出错?如果需要,请检查生成的 asm,但它 100% 不受支持。
或者它可能最终使用了更多的寄存器,并且由于它 naked
没有正确地 save/restore 调用保留寄存器?我自己还没有查看代码生成的裸函数。
你确定这个函数需要naked
吗?我想那是因为你将 lr
操纵到 return 到新的上下文。
如果你不想只在 asm 中编写更多逻辑,也许让这个函数的调用者做更多的工作(也许传递给它指针 and/or 布尔参数更简单地告诉它它需要做什么,所以你的输入已经在寄存器中,你不需要访问全局变量)。
这是一个已经存在并且有效的函数的开始;注释行是我添加的,其目的是切换引脚。
inline __attribute__((naked))
void CScheduler::SwapToThread(void* pNew, void* pPrev)
{
//*(volatile DWORD*)0x400FF08C = (1 << 14);
if (pPrev != NULL)
{
if (pPrev == this) // Special case to save scheduler stack on startup
{
asm("mov lr,%0"::"p"(&CScheduler_Run_Exit)); // load r1 with schedulers End thread
asm("orr lr, 1");
当我取消注释添加时,我的硬故障处理程序将执行。我知道这与 naked
函数有关,但我不明白为什么简单的赋值会导致问题。
两个问题:
- 为什么这条线会触发硬故障?
- 如何在这个函数中执行这个赋值?
幸运的是你以前版本的功能碰巧没有崩溃。
唯一可以安全地放入 naked
函数中的是纯 Basic Asm 语句。 https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html。您可以将其拆分为多个 Basic Asm 语句,而不是 asm("insn \n\t"
/ "insn2 \n\t"
/ ...);
,但您必须自己在 asm 中编写整个函数。
While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
如果您想 运行 来自裸函数的 C++ 代码,您可以 call
常规函数(或者 bl
在 ARM 上,jal
在 MIPS 等.), 遵循标准调用约定。
请问本案的具体原因是什么?也许在寄存器中创建该地址会踩到函数参数,导致分支出错?如果需要,请检查生成的 asm,但它 100% 不受支持。
或者它可能最终使用了更多的寄存器,并且由于它 naked
没有正确地 save/restore 调用保留寄存器?我自己还没有查看代码生成的裸函数。
你确定这个函数需要naked
吗?我想那是因为你将 lr
操纵到 return 到新的上下文。
如果你不想只在 asm 中编写更多逻辑,也许让这个函数的调用者做更多的工作(也许传递给它指针 and/or 布尔参数更简单地告诉它它需要做什么,所以你的输入已经在寄存器中,你不需要访问全局变量)。