代码之家  ›  专栏  ›  技术社区  ›  joeforker

为什么在调用main()时avr gcc会费心保存寄存器状态?

  •  2
  • joeforker  · 技术社区  · 15 年前

    avr-gcc程序中的main()函数将寄存器状态保存在堆栈上,但是当运行时调用它时,我知道在微控制器上没有任何东西可以返回。这是浪费公羊吗?如何防止这种状态保存?

    5 回复  |  直到 15 年前
        1
  •  3
  •   jcoder    15 年前

    最有可能的是,main只是在同一个标准函数中编译的。在C语言中,这很有必要,因为你可以从某个地方调用它。

    请注意,在C++中,调用主递归是非法的,因此C++编译器可能能够对其进行优化。但在C语言中,正如您的问题所述,递归调用main是合法的(如果是坏主意的话),因此需要以与任何其他函数相同的方式编译main。

        2
  •  6
  •   Darron    15 年前

    编译器如何确保不会递归调用main()?

        3
  •  4
  •   Nils Pipenbrinck    15 年前

    都是关于C标准的。

    没有什么能阻止你在某个时候离开主管道。你可能不会在你的程序中这样做,但其他人可能会这样做。

    此外,还可以通过 atexit 运行时函数。这些函数需要一个定义好的寄存器状态才能正确执行,保证这一点的唯一方法是保存和恢复主寄存器。

    这样做甚至有用: 我不知道AVR的情况,但其他的微控制器在完成工作并等待重置时,会进入低功耗状态。从清理处理程序执行此操作可能是一个好主意,因为如果以正常方式退出主处理程序,则会调用此处理程序 (就我而言)如果你的程序被一个终止信号中断。

        4
  •  1
  •   Turbo J    15 年前

    如何防止这种状态保存?

    唯一能做的就是编写自己的C启动程序。这意味着会弄乱汇编程序,但是您可以跳到main()而不是仅仅调用它。

        5
  •  1
  •   Yann Vernier    15 年前

    在我使用AVR GCC4.3.5进行的测试中,它只在不太优化的情况下保存寄存器。正常水平(-os或-o2)会导致推送指令优化。 您可以在函数声明中进一步指定它不会返回 __attribute__((noreturn)) . 用-fwhole程序进行全程序优化也很有用。

    avr libc中的初始代码使用call跳转到main,因为它指定了main 可以 返回,然后跳到出口(声明为no return,因此不生成调用)。如果你认为太多,你可以链接你自己的变体。exit()反过来只会禁用中断并进入一个无限循环,有效地停止程序,但不会节省任何电源。如果main()从不返回或调用exit(),则这是四条指令和两个字节的堆栈内存开销。