内部裸函数-如何进行简单分配

时间:2019-01-19 00:34:44

标签: c++ gcc assembly inline-assembly

这是已经存在并起作用的功能的开始;该注释行是我的补充,其目的是切换图钉。

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函数有关,但我不明白为什么简单的赋值会引起问题。

两个问题:

  1. 为什么这条线会触发硬故障?
  2. 如何在此功能内执行此分配?

1 个答案:

答案 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传递给它以更简单的方式告诉它需要做什么,因此您的输入是已经在寄存器中,您无需访问全局变量。