这是已经存在并起作用的功能的开始;该注释行是我的补充,其目的是切换图钉。
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
函数有关,但我不明白为什么简单的赋值会引起问题。
两个问题:
答案 0 :(得分:3)
很幸运,您以前的功能版本正常运行而没有崩溃。
可以唯一放到naked
函数中的是纯Basic Asm语句。 https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html。您可以将其拆分为多个基本Asm语句,而不是asm("insn \n\t"
/ "insn2 \n\t"
/ ...);
,但是您必须自己在asm中编写整个函数。
虽然使用扩展的asm或将基本的asm和C代码混合使用似乎可行,但不能依靠它们可靠地工作并且不受支持。
如果您想通过裸函数运行C ++代码,则可以call
常规函数(或ARM上的bl
,MIPS上的jal
等),然后执行标准的调用约定。
由于这种情况的具体原因?也许在函数args上的寄存器中创建该地址,导致分支出错?如果需要,请检查生成的asm,但100%不支持。
也许它最终使用了更多的寄存器,并且由于它的naked
没有正确保存/恢复调用保留的寄存器?我还没有亲自看一下代码生成器中的裸函数。
您确定此功能需要为naked
吗?我猜那是因为您操纵lr
返回到新的上下文。
如果您不想只在asm中编写更多的逻辑,则可以让此函数的调用者做更多的工作(并可以将它的指针和/或布尔args传递给它以更简单的方式告诉它需要做什么,因此您的输入是已经在寄存器中,您无需访问全局变量。