【问题标题】:STM32F4 not pushing/popping floating point registersSTM32F4 不推送/弹出浮点寄存器
【发布时间】:2016-08-31 13:47:58
【问题描述】:

我有密码

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);

明天我会检查是否有任何东西破坏了堆栈。

编辑2:

previousTemperature 所在的寄存器毕竟是被推送/弹出的。我没有注意到,因为在 dissasebly 中使用了 D9 寄存器,它遮住了 S18 和 S19。此外,snprintf(msg, 10, "%4.2f", value/100.0f); 中的 value 似乎是一些未初始化的垃圾。更正后,previousTemperature 始终保持不变。但是,为什么会发生这种情况对我来说是个谜,我担心真正的问题仍然存在,我只是无法观察到任何症状。

【问题讨论】:

  • previosTemperature 与常量的变量名不同:注意错字:(previos vs. previous)。不过,我认为这只是将代码复制到问题中的错误。如果您没有使用任何内联汇编,那么这听起来像是一个编译器错误,除非您以某种方式对编译器撒谎。
  • @PeterCordes 是的,这是一个错字。我不在任何地方使用内联汇编。
  • 如果它需要在函数调用中幸存下来,编译器应该把它放在一个 ABI 说是调用保留的寄存器中。我没有使用过 Keil 工具,但是为了让普通的 C 语义(比如变量保持其值!)正常工作,必须做任何特殊的事情是不正常的。
  • 您确定变量保存在寄存器中吗?它不能保存在堆栈中吗?在这种情况下,您可能有一个错误会破坏someNestedFunction 中的堆栈。尝试评论它的一部分,直到你将问题缩小到罪魁祸首(这当然假设注释掉对someNestedFunction的调用首先“解决”了问题)
  • 根据the ABI,s16-s31 是被调用者保存的,因此其中一个中间函数(或可能是中断处理程序)要么破坏堆栈,要么在编译器背后触摸 FP 寄存器。你想调试和修复那个,而不是在这个函数中绕开它。此外,在异常条目上调用者保存的寄存器的自动堆叠,也就是你所提到的,实际上与这里没有任何关系。

标签: c assembly arm keil compiler-bug


【解决方案1】:

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

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

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


更新:如果只是未初始化的浮点数,那并不能解释任何事情。

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

【讨论】:

  • 调用看起来像:char msg[10]; snprintf(msg, 10, "%4.2f", value/100.0f);,其中 value 是一个未初始化的浮点数。
  • @mactro:嗯,读取未初始化的浮点数并不能解释它。 :/ snprintf 仍应仅将 NaN 或一些十进制数字打印到 msg 中,并且始终以空值终止字符串。 (与 strncpy 不同)。
猜你喜欢
  • 2016-12-04
  • 2020-02-06
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多