-4

我有下一个代码:

#include <math.h>

int x;
float Temp = 0;

void main(){

x = 2;

for(;;){
   Temp=log(20);
}
}

我将我的代码缩短到重要的行。我遇到的问题是,一旦 x 被声明为 2,然后我执行 log() 函数,此计算将更改为 x 变量并将其更改为一个巨大的值。

Codewarrior(我使用的 IDE)说 Temp 变量位于 0x0102 位置,而 x 变量位于 0x0108 位置。

我需要 x 作为“MCUinit.h”中的函数,因此 x 变量不大于 5 很重要,并且 codewarrior 在执行 log 后给出 5000 甚至更大(无论如何)

我怎么能这样做 log() 不会改变其他变量?

谢谢

在执行 log() 函数之前。 https://ibb.co/6ZHh6D0

在做 log() 函数之后。 https://ibb.co/Np99Sz4

4

2 回答 2

2

这是一个明显的堆栈溢出。S08 是一个资源极其有限的 8 位 MCU。它不是个人电脑。它没有 FPU。这意味着您永远不能也不应该使用浮点运算。时期。并且一般避免使用 32 位算术。

当你卷起 math.h 时会发生什么,Codewarrior 注入了一个夸张的软件浮点库,完全屠杀了整个 MCU 中所有可用的内存和 CPU 资源,把你的程序变成了无用的烂摊子。一个log调用显然足以杀死堆栈。我并不感到惊讶,默认情况下您有大约 100-200 字节的堆栈。发生这种情况时,堆栈会溢出到存储变量和的.data/.bss内存区域,在这些区域写入乱码时会破坏它。xTemp

如果您确实需要使用浮点计算,那么运气不好,您选择了错误的 MCU。应该选择 Cortex M4。

此外,您应该始终放置堆栈,以便它增长(它是一个向下计数的 SP)进入无害的内存区域,而不是进入.data/.bss部分。为什么 Codewarrior 默认不这样做是很奇怪的。让堆栈增长到寄存器映射也不理想,但如果您没有使用 0x70 附近的所有定时器外设,那么与破坏程序中的所有变量相比,这至少是一个不太糟糕的情况。

于 2019-10-09T10:56:48.277 回答
-2

不知何故,我想出了一个可能的解决方案。由于我的编程水平,我想这不是最好的解决方案,但它确实有效。

当我的程序执行行时Temp=log(20),它的结果有点混乱,因为它在 RAM 中更改了太多的值,其中包含某种变量,然后 log() 给了我自己的值和垃圾,从它的位置 0x0100 开始粉碎。所以我所做的就是在'float Temp[10]中改变'float Temp',然后我在那个数组中收集了真正的勇气和垃圾。所以我只需要采取有兴趣的勇气。

谢谢大家。无论如何,我仍然在这里听取新的建议。

于 2019-10-10T06:44:02.243 回答