金牌会员
 
- 积分
- 2246
- 金钱
- 2246
- 注册时间
- 2010-12-16
- 在线时间
- 202 小时
|

楼主 |
发表于 2013-8-13 20:37:05
|
显示全部楼层
回复【8楼】ofourme:
---------------------------------
有OS反而不用了,因为基本OS都有栈检查.原理和这个一样.
Stack_Mem位置是由链接器决定的,LZ的头文件也写了,需要从栈配置文件导出,不一定是在RAM起始地址.比如MDK的内存分配,最后面是栈,栈前面是堆,堆前面是变量区.
当然,把栈加载到内存区的起始地址也可以做到溢出必进hardfault,要么在汇编增加绝对定位,要么修改分散加载文件.这就是个人风格问题了,我自己喜欢代码尽量通用,而且零修改重用.
这说到我写这个代码的原因,我一直以为栈是像你说的分配到内存的起始地址,结果有一天,我发现我错了...考虑到这里用MDK的用户基数,就放出来了.
这里是首发,也是唯一发表.
ps:堆是堆,栈是栈,虽然理解你说的是栈,但看着看着还是要转一下弯.
堆是必须通过代码只是分配的动态内存,C的malloc/calloc/free,C++的new/delete,还有原子写的,有专门函数负责分配和回收,可能还有一些维护函数,所管理的内存空间.
栈是无需用户自己调用指令申请的.栈不是完全硬件实现,完全硬件实现的是PC的出入栈,工作区的出入栈还是有具体的代码实现的,只是编译器会在变量使用前调用函数/指令入栈,生存期结束就出栈还原工作区.这些都不用用户实现,就像硬件自动完成那样.而且有些代码,比如
int func(void)//无优化编译
{
int a = 1;
int b = 2;
return (a & 0x3) | (b * 4);
}
这种,栈的使用将会大于2*sizeof(int).
上面的代码在编译器优化过之后,就会变成消耗1*sizeof(int)的栈,用于直接赋值1,然后对其入栈返回.如果是堆,无论用户用不用,申请成功就拿到了,不想用的话,程序也不会自动回收.
这里不是指Java之类有垃圾回收的平台,这些平台是在中间层做了个壳,任何操作都有检查,所以代码操作安全而且低效. |
|