【问题标题】:How stack pointer works堆栈指针的工作原理
【发布时间】:2018-03-07 21:27:04
【问题描述】:

我正在尝试为 atmega328p micro 创建一个多线程内核,为此我需要知道它的堆栈指针是如何工作的。

【问题讨论】:

  • 如果您向我们展示一些代码 sn-ps 和示例输入/输出,将会有所帮助。见stackoverflow.com/help/mcve
  • 优化可能只为嵌套函数调用创建一个返回点。甚至内联所有这些...
  • 我已经编辑以提高英语 - 请检查我没有破坏你的意思。我还更改了标签 - 语言不是那么重要(你会收到很多关于使用 both C 和 C++ 标签的回击),这方面的专家很可能是Arduino 专家,而不是 C 专家。如果你也想要一个语言标签,请选择一个,而不是两个。
  • /* 代码的输出是:8700 8700 8700 8700 正确的输出需要是:8700 8698 8696 8694 */ void func3() { Serial.println(SP); } void func2() { Serial.println(SP);函数3(); } void func1() { Serial.println(SP);函数2(); } void setup() { Serial.begin(9600);序列号.println(SP);函数1(); } 无效循环() { }
  • 另问:forum.arduino.cc/index.php?topic=533773 如果您打算这样做,请考虑周到添加指向您交叉发布的其他地方的链接。这将使我们避免因重复工作而浪费时间,并帮助有相同问题并找到您的帖子的其他人发现所有相关信息。

标签: c++ arduino avr atmega avr-gcc


【解决方案1】:

很可能,您的函数被正确地内联,所以实际上一切都在setup() 中直接完成,不涉及函数调用。如果你想强制禁用它们的内联(查看堆栈指针的变化),你可以应用 gcc noinline 属性。

void __attribute__ ((noinline)) func1() {
    ...
}

如果这仍然不起作用,则 gcc 可能正在应用尾调用优化。在这种情况下,使您的函数不易受此优化影响的一种简单方法是在调用之前和之后打印SP

【讨论】:

  • 嗨,像答案一样的接缝,将 attribute ((noinline)) 放在函数名称之前,并在调用前后打印 SP。我试着用 Atmel Studio 来做这件事,这里工作正常,我将尝试完成三个任务,如果它工作,彼此将打开一个 LED,我会将代码放在这里以帮助任何想要做同样事情的人。感谢您的帮助。
  • 是的,我希望没有noinline,一切都会被内联,即使有了它,尾部调用也会优化为跳转。在调用之后添加一些事情来做尾调用优化优化。现在,如果我的回答帮助您考虑将其标记为已接受(赞成/反对票附近的勾号)按钮 - 它给您 5 分,给我 15 分,并表明问题确实有解决方案。谢谢!
猜你喜欢
  • 2020-09-29
  • 2021-12-26
  • 2015-11-16
  • 2013-01-20
  • 2015-12-02
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多