我有密码
const float previousTemperature = getTemperature();
someNestedFunction();
someOtherActions();
setTemperature(previousTemperature);
我的问题是 someNestedFunction();
previousTemperature
被修改了。我查看了反汇编,但找不到任何指令可以在调用之前推送或弹出存储 previousTemperature
的寄存器。
我检查了 ARM documentation它指出:
The other registers in the FPU, that is, S0-S15 and FPSCR, are always saved automatically.
我的变量存储在 S18 中,那么如何确保它能正确保存和恢复?我想找到一个可以避免与 Asm 混淆的解决方案。
我的处理器是 STM32F437ZGT,我使用 Keil uVision 5 编译器。
编辑:
到目前为止,我已经尝试对 someNestedFunction()
的内容进行注释,以找出究竟是什么修改了我的变量所在的寄存器。事实证明,它被调用
snprintf(msg, 10, "%4.2f", value/100.0f);
明天我会检查是否有任何东西破坏了堆栈。
编辑2:
previousTemperature
所在的寄存器毕竟被压入/弹出。我没有注意到,因为在 dissasebly 中使用了 D9 寄存器,它隐藏了 S18 和 S19。此外,snprintf(msg, 10, "%4.2f", value/100.0f);
中的 value
似乎是一些未初始化的垃圾。更正后,previousTemperature
始终保持不变。然而,为什么会发生这种情况对我来说是个谜,恐怕真正的问题仍然存在,我只是无法观察到任何症状。
最佳答案
很好的侦探工作,发现 reg 被保存为 D9。
你在说 snprintf 中的哪种未初始化垃圾?你传递了一个虚假的指针吗?如果是这样,那么 snprintf
可能会覆盖您的变量在堆栈中保存/恢复的位置,因为它收到的 buf 指针告诉它这样做。
堆栈上的损坏数据通常会导致错误的返回地址(导致段错误)或变量中的错误数据,这些数据本应在函数调用后继续存在。
更新:如果只是未初始化的 float ,那什么也解释不了。
建议:在最外层保存和恢复D9的地方设置断点。在保存它的堆栈地址上设置一个观察点,这样您就可以检测到内存何时被覆盖,同时它仍然保存着变量的保存值。
关于c - STM32F4 不压入/弹出浮点寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39251479/