全局变量被破坏

时间:2019-10-09 06:59:48

标签: c stack embedded codewarrior 68hc08

我有下一个代码:

#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。

“ MCUinit.h”中的函数需要x,因此x变量不大于5是很重要的,代码日志在执行log(what(whatever))之后会给出5000甚至更大的值

我该怎么做,以使log()不会更改其他变量?

谢谢

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

执行log()函数之后。 https://ibb.co/Np99Sz4

2 个答案:

答案 0 :(得分:2)

这是明显的堆栈溢出。 S08是一个资源非常有限的8位MCU。它不是PC。它没有FPU。这意味着您不能并且永远不要使用浮点算术。期。并避免一般使用32位算法。

当您汇总math.h时,会发生以下情况:Codewarrior注入了一个庞大的软件浮点库,从而完全扼杀了整个MCU中所有可用的内存和CPU资源,从而使程序变成了无用的混乱。单个log调用显然足以杀死堆栈。我并不感到惊讶,默认情况下,您有大约100-200字节的堆栈。当发生这种情况时,堆栈会溢出到.data / .bss存储区中,其中存储了变量xTemp,并在这些区域写入乱码时将其破坏。 / p>

如果实际上需要使用浮点计算,那么倒霉,您选择了错误的MCU。应该选择了Cortex M4。

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

答案 1 :(得分:-2)

我以某种方式提出了一个可能的解决方案。由于我的编程水平,我认为这不是最好的解决方案,但是它可以工作。

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

感谢伊维农。 无论如何,我仍然在这里听到新的建议。