STM32F4不推/弹出浮点寄存器

时间:2016-08-31 13:47:58

标签: c assembly arm keil compiler-bug

我有一个代码

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始终保持不变。然而,为什么这种情况发生对我来说是一个谜,我担心真正的问题仍然存在,我只能观察到任何症状。

1 个答案:

答案 0 :(得分:-1)

很好的侦探工作,发现该reg被保存为D9。

你在谈论snprintf中有哪种未初始化的垃圾?你传了一个虚假的指针吗?如果是这样,那么snprintf可能会覆盖堆栈中保存/恢复变量的位置,因为它收到的buf指针告诉它这样做。

损坏堆栈上的数据通常会导致错误的返回地址(导致段错误)或者在函数调用中存在的变量中的错误数据。

更新:如果它只是未初始化的浮点数,则无法解释任何内容。

建议:在保存和恢复D9的最外部位置设置断点。在保存它的堆栈地址上设置一个观察点,这样您就可以检测到内存被覆盖的时间,同时仍保留变量的保存值。