本帖最后由 冷漠 于 2010-7-15 21:25 编辑
几个问题:
1、编译器、连接器把堆栈段定位在IDATA内所有段的最后面,也即内存IDATA高端;
2、中断堆栈被定位在堆栈段内的最后面,即IDATA最顶端;所以堆栈段的安全余量设置,实际上是中断堆栈深度的配置。
3、如果不考虑系统堆栈的安全余量设置,一个没有二级中断嵌套的一级中断堆栈深度应该是13字节。——为什么?
4、系统中断的安全余量配置应该是……字节。——为什么?
下面详细说明:
1、整个51内存256字节。C51首先分配全局静态变量在IDATA低端,接着分配的是项目中所有函数的参数和局部变量共享覆盖区——也属于全局静态变量区(段)。(有没有动态数组区段冷漠不知道也不关心,)然后就是系统堆栈段,其栈底指针?STACK——由C51自动生成,栈顶应该是IDATA顶端——0xFF。系统堆栈深度=0xFF-(?STACK)。
如果项目中含有汇编模块,那么系统堆栈?STACK中还包含汇编模块私有堆栈STACK(指针指向)如果项目中包含有reentrant 重入函数 foo,那么系统堆栈中还包含有每个foo所属的私有模拟堆栈simulated stack;它也是C51为每个reentrant 函数自动分配的。对于interrupt 属性函数,C51为其分配中断函数私有堆栈……还有硬件堆栈hardware stack 的概念(函数调用CALL或者中断发生时由硬件自动压入PC的堆栈。)
所以,一个系统堆栈段内分配了很多私有堆栈,所谓私有,应该是操作系统概念,用在这里是为了与系统堆栈?STACK 区分概念,例如,当一个中断事件发生时,它所打断的后台程序 F1 所正在使用的堆栈,是不可能与中断函数堆栈共享的。——2者堆栈都是私有的。
由于中断函数具有最高优先权,且堆栈独立,所以我说中断函数堆栈必然处在所有其它私有STACK之上,是IDATA最顶端的堆栈;——安全余量必是在中断堆栈之上分配。
……Cx51编译器会(自动——冷漠注释)产生一个?STACK的堆栈段,该段将被自动定位到IDATA空间的顶部。……一般不需要特别指定?STACK的位置,对于具有几个堆栈的汇编程序才需要采用STACK命令。需要注意的是,重新定位?STACK 段必须非常小心,因为可能会破坏 DATA 或 IDATA 空间的变量而导致程序无**常运行。
——摘自《Keil Cx51 V7.0 单片机高级语言编程与uVision2 应用实践》 徐爱钧编著 P640
2、 待续…… |