OneRain 发表于 2018-6-17 15:31:28

求助,51单片机程序数据溢出。。。(keil函数指针)

本帖最后由 OneRain 于 2018-6-18 13:18 编辑

很久没有搞51内核的MCU了,发现程序的局域变量数据经常被改的莫名奇妙。。。函数级数在4-5级,不是太深,但是好像经常表现出溢出导致局域变量数据被改。。。
见图:,函数1退出后,函数2的局域变量数据全部被修改的不成样子。。。
Program Size: data=74.1 xdata=207 const=1351 code=13749,我程序占有量发现data变量留的足够有啊。。。。求那个大神告知原因啊!!!
修改原因:添加具体错误原因,好让以后有人遇到这种错误的人,搜索到关键字的搜索到这个解决贴!!!{:lol:}

OneRain 发表于 2018-6-17 15:35:22

补充一下,在进入函数1前,函数2的局域变量数据都是正确的,即使函数1执行也是完全没问题,包括函数1进入下一级函数,都没问题,但是只要函数1退出来,函数2的局域变量数据就全部会变。。。

lzf713 发表于 2018-6-17 18:50:48

局部变量有时候共用相同地址的RAM,但是,不同函数调用时候,会将原来的现场保护好的。比如有两个函数,一个叫a,一个叫b,他们都有一个局部变量,分别是aa,bb,并且共用同地址的存储器。正在执行函数a时候,使用aa。如果函数a还没有结束就调用函数b,在执行函数b之前就将aa压入堆栈了。当执行完函数b之后,自动将aa从堆栈里面弹出,恢复原来状态。

OneRain 发表于 2018-6-17 18:53:36

lzf713 发表于 2018-6-17 18:50
局部变量有时候共用相同地址的RAM,但是,不同函数调用时候,会将原来的现场保护好的。比如有两个函数,一 ...

现在问题的关键就是,退出函数调用的时候,局部变量会被修改。。。导致值出现错误!!!有点操蛋。。。。

lzf713 发表于 2018-6-17 18:54:54

有没有开中断?

OneRain 发表于 2018-6-17 19:07:57

lzf713 发表于 2018-6-17 18:54
有没有开中断?

开了一个心跳中断,我把总中断关了一个鸟样!!!

OneRain 发表于 2018-6-17 19:09:15

lzf713 发表于 2018-6-17 18:54
有没有开中断?

我都在想要不要用IAR的51了,感觉有点慌!!!!{:mad:} {:mad:} {:mad:}

OneRain 发表于 2018-6-17 19:37:17

终于找到原因了。。。函数指针的锅!!!不知道C51怎么实现的。。。坑爹啊!!!

OneRain 发表于 2018-6-17 19:40:53

具体情况,看各位有啥好的解决办法。。。。
typedef mic_bool_def (*aaa_def)(uint8_t reg, uint8_t amount, uint8_t *pd);
定义了一个函数指针类型,然后,用这个类型起了个变量
aaa_def bbb;
一个实现函数是:
mic_bool_defccc(uint8_t reg, uint8_t amount, uint8_t *pd);
现在的情况是:
bbb = ccc;
然后执行bbb(参数),就出现上面的问题,但是直接执行ccc(参数),完全OJBK。。。。问题来,各位怎么看这个问题。。。

OneRain 发表于 2018-6-17 20:19:20

有点想换IAR了,百度了一下,IAR好像比较遵循C标准。。。但是问题来了,kei支持的厂商多,应该这么来说,很多厂商支持keil比较多。。。。有些国产MCU压根就木有IAR支持。。。搞头文件还得自己来,太痛苦了!!!然后我也查了一下keil对于函数指针的支持,好像有点操蛋,不太遵循C标准。。。

OneRain 发表于 2018-6-17 21:42:58

最后的解决办法顺带也写上,如果只是少量的指针,可以用keil的OVERLAY来搞,但是用的比较多,还是不建议,因为非常容易疏漏。。。最后我个人的解决办法,当然是不用函数指针啦,直接用switch啦!!!!!{:mad:}{:mad:}{:mad:}

OneRain 发表于 2018-6-17 21:44:10

对了,在补充一句,就是用函数指针的时候,函数参数也有限制,如果你用OVERLAY来实现的话,最多好像是3个。。。具体原因没有去深究啦。。。还是老老实实的用switch好啦!!!{:lol:}{:lol:}{:lol:}
页: [1]
查看完整版本: 求助,51单片机程序数据溢出。。。(keil函数指针)