几个问题:
1、编译器、衔接器把仓库段定位在IDATA内一切段的最终面,也即内存IDATA高端;
2、中止仓库被定位在仓库段内的最终面,即IDATA最顶端;所以仓库段的安全余量设置,实践上是中止仓库深度的装备。
3、假如不考虑体系仓库的安全余量设置,一个没有二级中止嵌套的一级中止仓库深度应该是13字节。——为什么?
4、体系中止的安全余量装备应该是……字节。——为什么?
下面具体阐明:
1、整个51内存256字节。C51首要分配大局静态变量在IDATA低端,接着分配的是项目中一切函数的参数和局部变量同享掩盖区——也归于大局静态变量区(段)。(有没有动态数组区段冷酷不知道也不关心,)然后便是体系仓库段,其栈底指针?STACK——由C51主动生成,栈顶应该是IDATA顶端——0xFF。体系仓库深度=0xFF-(?STACK)。
……Cx51编译器会(主动——冷酷注释)产生一个?STACK的仓库段,该段将被主动定位到IDATA空间的顶部。……一般不需求特别指定?STACK 的方位,关于具有几个仓库的汇编程序才需求选用STACK指令。需求留意的是,从头定位?STACK 段有必要十分当心,由于或许会损坏 DATA 或 IDATA 空间的变量而导致程序无**常运转。
冷酷同学啊, 引证就引证吧, 干么望文生义,还搀杂私货, 这样欠好嘛。
1)中止仓库最大或许深度是15(2+5+8)字节, 不是 13。原因现已给出, 不再重复。
2)8051 运转时有只需一个一致stack, 不存在 中止仓库 以及 非中止仓库, os 或程序人为操作stack 另当别论。
3)仓库段定位在IDATA一切段的最终面, 把空白区悉数作为stack 这十分天然, 并且 8051 stack grow *UP*, 用脚后跟想想就会了解。c51:
While the 8051 architecture restricts the stack to internal memory, it may be located at any point therein. The stack typically starts following the last individual variable allocation in internal memory and is free to grow *up* through whatever memory remains.
4)私有仓库是****编译时*****的中心产品, 用于最终衔接核算, 衔接时linker 一致定位。方针代码*****运转时*******,只需一个stack. 一切的函数调用, 中止断点, 以及中止register维护都在一个 stack 里。这是最基本的****知识***问题!!!! os 的人为切割切换 stack 完全是另一个概念。
讨教 冷酷大师:
您所言的“后台仓库”,实践上是C言语中的软仓库,担任分配在大局静态变量空间同享掩盖区,其长度为每个独立的后台函数的私有仓库之和!
您所言的“前台仓库”,实践是51单片机中真实的硬件仓库,担任中止呼应需求维护的变量,子函数调用等硬性的压栈出栈操作!
C言语的运转是依托这一软一硬两个仓库和谐作业,您所言的:一高(端)一低(端),一小一大,一前(台)一后(台)。便是指这一软一硬两个仓库。
不知俺了解的对不对?
提一个问题:什么是仓库?
假如,仓库是指硬件仓库,那个由仓库指针SP所操控的,那当然只需一个仓库,没有什么私有的仓库,包含中止等,都是往这个仓库上放,
假如自己在函数里(操作体系也不过是一些函数,一些共用的函数集罢了)界说一个仓库,那个仓库就欠好说,那叫软仓库。
一个处理体系有且只需一个当时仓库,便是有SP寄存器操控的那个。不管是中止产生仍是函数调用,都是用这个SP定位。其他什么私有仓库不过是程序修改SP而完成的。
仓库的深度是不宜准确设置的,除非你的程序很简单,或根本就没有中止嵌套,这样你能够很简单核算出体系或许最大仓库。否则没什么好说的,将必要的内存设置好,其他的通通留给仓库(横竖闲着也是闲着)。
特别阐明一点:
“reentrant”的 “simulated stack” 仅仅为了模仿经过 stack 传递参数(这是大多数c 编译器的做法)以完成重入,实践完成上有点杂乱,是Rn寄存器再加上一个“simulated stack” 数据区(具体情况能够看看反汇编)。
具体没看过编译手册,不过关于这句有些疑问:
其栈底指针?STACK——由C51主动生成,栈顶应该是IDATA顶端——0xFF
51仓库是向上成长型,刚开端栈顶应该在栈底那里,每次PUSH,往上加,直到最大0XFF.可是你这儿说栈顶应该在IDATA的顶端–OXFF,应该不对。
担任分配在大局静态变量空间同享掩盖区,其长度为每个独立的后台函数的私有仓库之和!
“软仓库”的提法十分附和。绝不是一般人所能了解到如此深入的。其它先不多说,——我还没讲到。可是上面红线部分我有贰言:就像后台一切非重入函数的参数传递和局部变量被分配在同享掩盖区相同,其长度应该是占用内存字节数最多的那个函数所占有的区域,其它函数分时同享这个区域。——而不是一切之和。这才是同享、掩盖的操作体系内存办理的办法和含义吧?
赞同12楼,说的太好了。这儿的确欠好得出仅有定论;记住ayb_ice具体证明过,仓库长度开端为什么是1字节。主张去看看他的帖子。我不能确认仅有定论的理由:
1、?STACK是由编译器主动生成的体系仓库段,——一切含有PUSH / POP指令操作的函数,都在这个体系仓库段里享有自己的接连仓库空间(留意是动态的。)?STACK所指向的体系仓库段被分配在体系一切其它RAM段的最终面。?STACK肯定是一直指向体系仓库栈底,衔接定位之后就不行移动的;
2、“最终面的”后边还能组织有东西么?冷酷以为编译器不行能反复无常,所以以为没有了,所以冷酷说栈顶是IDATA的顶。12楼能够说栈顶是移动的,移动上限是IDATA顶端。冷酷坚决赞同。
?STACK的定位是衔接器确认的,和编译器无关。LZ现已举了书上的Keil阐明书译文, 衔接器是否主动把?STACK定位在IDATA顶端?仍是需求人工履行STACK衔接指令之后才行?冷酷也有疑问?不太清楚。
S
请你细心看我的原话,没有了解就不要乱引证
我是说KEIL默许的仓库长度是1字节<,能够改,只需编译器能分配一个字节的空间,就不会报错>,但其实一切没有被编译器运用的IDATA空间都是仓库,当然中心的空隙不算
对自己在12楼的话解释一下
关于栈顶的了解其实和LZ是相同的,仅仅说法略微不同。
仓库指针SP的规模,最小叫栈底,最大叫栈顶。SP在栈底和栈顶之间活动。所以本例中,栈顶是IDATA顶端0XFF,这么了解没错。
我12楼这么说,我是这么了解的
由于仓库指针SP的值是栈顶的地址,所以SP活动,那么栈顶也跟着活动的。(SP指向栈顶)
栈顶的规模:最小值即栈底,最大值即 最大栈顶值。
其实和LZ的意思是相同的。
冷酷有另一观念:
C51对用户来说没有SP的概念,你是C51用户你不是编译器作者,要么你说自己只用汇编,那咱们评论不在一个层次,必定留意不要以汇编的概念来了解C编 译器,?STACK 便是编译器生成的仓库段,并且我以为这个?STACK 以上编译器不行能分配其它数据段。所以从?STACK以上都是仓库段,即便有许多不必的空间,也不行能被谁占用,编译器没有让谁用。——这不是汇编言语编 程,程序员无法操控SP的。