阻止 Keil uvision 在函数调用时推送寄存器

Stop Keil uvision from pushing registers on function call

当我从 main() 调用包含无限循环的 C 函数时,它会在执行该函数之前将一些寄存器压入堆栈。由于该函数包含一个无限循环,因此这些寄存器永远不会弹出。

举个例子,

void My_Func (void)
{   
    int flag_1 = 1;

    while(1)
    {       
        if(counter > 5 && flag_1)
        {
            flag_1 = 0;
        }

        else if(counter > 550 && flag_1)
        {
            flag_1 = 0;
        }
   }    
}


int main(void)
{
    My_Func();

    return 0;
}

这里counter是一个全局变量

当我调用 My_Func() 时,它会在执行函数之前推动 R4、R5、R6。反汇编看起来像这样,

0x080004BC B470      PUSH     {r4-r6}

然后函数执行开始。但是由于函数内部有一个无限循环,寄存器永远不会弹出。

有什么方法可以在不修改函数定义的情况下阻止 KEIL IDE 在执行函数之前压入寄存器?

您可以在函数声明中使用 __attribute__((noreturn)) 来通知编译器该函数不会返回。根据 Arm Keil documentation 这个属性被描述为:

9.41 __attribute__((noreturn)) function attribute Informs the compiler that the function does not return. The compiler can then perform optimizations by removing code that is never reached.

Usage Use this attribute to reduce the cost of calling a function that never returns, such as exit(). Best practice is to always terminate non-returning functions with while(1);.

这应该可以防止编译器生成将寄存器 R4 推送到 R6 的函数序言代码。