我有一个代码
const float previousTemperature = getTemperature();
someNestedFunction();
someOtherActions();
setTemperature(previousTemperature);
我的问题是someNestedFunction();
previousTemperature
被修改了。我看过反汇编,在调用之前,我找不到任何会推送或弹出存储previousTemperature
的寄存器的指令。
我已检查过ARM documentation,并声明:
FPU中的其他寄存器,即S0-S15和FPSCR,总是如此 自动保存。
我的变量存储在S18中,那么如何确保它能够正确保存和恢复?我想找到一个可以避免搞乱Asm的解决方案。
我的处理器是STM32F437ZGT,我使用的是Keil uVision 5编译器。
修改
到目前为止,我试图评论someNestedFunction()
的内容,以找出究竟修改了我的变量所在的寄存器的内容。事实证明,通过调用
snprintf(msg, 10, "%4.2f", value/100.0f);
明天我会检查是否有任何东西破坏了堆栈。
EDIT2:
毕竟推送/弹出previousTemperature
所在的寄存器。我没有注意到,因为使用D9寄存器,它会影响S18和S19。此外,value
中的snprintf(msg, 10, "%4.2f", value/100.0f);
似乎是一些未初始化的垃圾。纠正后,previousTemperature
始终保持不变。然而,为什么这种情况发生对我来说是一个谜,我担心真正的问题仍然存在,我只能观察到任何症状。
答案 0 :(得分:-1)
很好的侦探工作,发现该reg被保存为D9。
你在谈论snprintf中有哪种未初始化的垃圾?你传了一个虚假的指针吗?如果是这样,那么snprintf
可能会覆盖堆栈中保存/恢复变量的位置,因为它收到的buf指针告诉它这样做。
损坏堆栈上的数据通常会导致错误的返回地址(导致段错误)或者在函数调用中存在的变量中的错误数据。
更新:如果它只是未初始化的浮点数,则无法解释任何内容。
建议:在保存和恢复D9的最外部位置设置断点。在保存它的堆栈地址上设置一个观察点,这样您就可以检测到内存被覆盖的时间,同时仍保留变量的保存值。