[51单片机] 51单片机开辟栈空间和STM32的区别在哪里?

[复制链接]
370|14
 楼主 | 2018-12-5 18:32 | 显示全部楼层 |阅读模式


我试了下新唐N76E003可以开辟256byte的局部数组,但是我想知道51单片机和STM32的区别,STM32的栈空间是自己设置的,局部变量存放在栈中,如果局部变量定义的变量大于开辟的栈的大小,就会覆盖全局变量的值,我想知道51单片机是怎么做到开辟256byte的局部变量的,它整个内部data才256byte,怎么做到开辟256byte局部变量数组
| 2018-12-5 19:00 | 显示全部楼层
N76E003为新唐高速1T 8051 单片机系列产品,提供18 KB Flash ROM、可配置Data Flash与高容量1 KB SRAM,支持2.4V 至 5.5V宽工作电压与-40℃至105℃工作温度,并具备高抗干扰能力 7KV ESD/4KV EFT。

高于256的叫Xdata, Keil编译器选large模式就行
| 2018-12-5 20:53 | 显示全部楼层
刚好占满允许空间总是觉得不太放心,还是分开一半放片内RAM一半放外部比较放心,个人愚见
| 2018-12-5 22:08 | 显示全部楼层
51 的堆栈空间只能在内部 256byte 中,  至于扩展的 256 字节, 可以用 pdata 或 xdata 处理.
| 2018-12-6 08:36 | 显示全部楼层
本帖最后由 ayb_ice 于 2018-12-6 08:38 编辑

你定义个这个试试
char idata acBuf[256];
肯定是不行的

这个可以
char xdata acBuf[256];

另外,STM32局部变量大于栈空间也不一定会出问题,这取决于你有多少空余空间
 楼主 | 2018-12-6 10:11 | 显示全部楼层
ayb_ice 发表于 2018-12-6 08:36
你定义个这个试试
char idata acBuf[256];
肯定是不行的

我定义的是局部变量数组,默认是放在xdata中的,程序暂时也没有出现问题,我想知道的是51栈默认的大小是多少,默认开辟栈的大小
 楼主 | 2018-12-6 10:11 | 显示全部楼层
雪山飞狐D 发表于 2018-12-5 19:00
N76E003为新唐高速1T 8051 单片机系列产品,提供18 KB Flash ROM、可配置Data Flash与高容量1 KB SRAM,支 ...

我定义的是局部变量数组,默认是放在xdata中的,大小是256byte,程序暂时也没有出现问题,我想知道的是51栈默认的大小是多少,默认开辟栈的大小
| 2018-12-6 11:26 | 显示全部楼层
18576478035 发表于 2018-12-6 10:11
我定义的是局部变量数组,默认是放在xdata中的,程序暂时也没有出现问题,我想知道的是51栈默认的大小是 ...

默认是一个字节大小(可以修改大小),但是没有被分配的idata空间其实都是堆栈,甚至已经分配的也是堆栈,因为堆栈自动改变,是不会检查是否出问题的,一般也无法检查

启动文件是这样定义堆栈的
RSEG    ?STACK
                DS      1
 楼主 | 2018-12-6 13:58 | 显示全部楼层
ayb_ice 发表于 2018-12-6 11:26
默认是一个字节大小(可以修改大小),但是没有被分配的idata空间其实都是堆栈,甚至已经分配的也是堆栈 ...

使用增强型51(xdata768byte)定义256byte局部数组程序会出问题吗?我测试可以开辟成功但是会不会导致局部变量覆盖全局变量的值
| 2018-12-6 14:00 | 显示全部楼层
18576478035 发表于 2018-12-6 13:58
使用增强型51(xdata768byte)定义256byte局部数组程序会出问题吗?我测试可以开辟成功但是会不会导致局 ...

只能定义在pdata或xdata空间,idata,data,bdata空间是不可以的
 楼主 | 2018-12-6 14:56 | 显示全部楼层
ayb_ice 发表于 2018-12-6 14:00
只能定义在pdata或xdata空间,idata,data,bdata空间是不可以的

好滴,谢谢
| 2018-12-6 21:59 | 显示全部楼层
keil c51函数内的变量(包括入口参数在内),如果超过了8个字节,会被分配在一个根据调用树计算好的静态堆栈上。和存储函数调用地址的sp指针的堆栈不是一个。
你如果选择了large模式,这个静态栈就在xdata里面。
如果函数有重入,有被可变函数指针间接调用,那么调用树就不是固定的,就不行了。
这样充分利用了ARM等CPU没有的直接寻址指令,访问堆栈上的数的效率比较高。比如 0x30的堆栈上存的数 inc 30h就可以直接加1。
如果不用这个方式,用gcc等职能堆栈的方式,那么 由于8051这个古老的cpu的堆栈指针不能间接寻址,指针少,指针间接访问的开销大等,导致效率低下很多。
 楼主 | 2018-12-7 18:07 | 显示全部楼层
linqing171 发表于 2018-12-6 21:59
keil c51函数内的变量(包括入口参数在内),如果超过了8个字节,会被分配在一个根据调用树计算好的静态堆 ...

大神说的太深奥了没听懂 ,            IDATA   00DEH     0001H     UNIT         ?STACK 我看我的m51文件stack 应该定义在deh-ffh区域内吧
| 2018-12-7 19:19 | 显示全部楼层
18576478035 发表于 2018-12-6 10:11
我定义的是局部变量数组,默认是放在xdata中的,大小是256byte,程序暂时也没有出现问题,我想知道的是51 ...

编译器比如keil 那里应该可以看到大小,也可以自己修改,或者启动文件里面包含有
| 2018-12-7 22:40 | 显示全部楼层
18576478035 发表于 2018-12-7 18:07
大神说的太深奥了没听懂 ,            IDATA   00DEH     0001H     UNIT         ?STACK 我看我的m51文 ...

是的,你的这个项目的程序调用的堆栈是在DE开始的,只有一个字节,最多可以用到FF。
你的程序如果没有中断的话,最多能调用(FF-DE+1)/2=16级左右,如果有中断,很可能就堆栈溢出而崩溃了。建议给堆栈多留点空间。
局部变量不在这个堆栈上,在寄存器和  _DATA_GROUP_ 这个里面。
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

关闭

热门推荐上一条 /6 下一条

快速回复 返回顶部 返回列表