“模块私有栈“:
这个术语在徐爱钧编著P640里以及 keil 的网站里都没有, 显然是冷漠杜撰的, 如同"递归可重入“
Bl51 stack 命令参数看似可以设定一个”模块私有栈”, 其实这个stack 命令参数的作用是为了汇编模块,而且是需要重新设置 sp 的汇编模块。 C 程序不需要关心 sp, 更不鼓励用户设置 sp. 只有汇编不得不这么做。汇编不得不自己设置 sp,不得不自己控制push/pop.
假设某个第三方的汇编模块里改写 sp (由于特殊的应用),此人为了通用,没有直接设置 sp 为一个固定值,而是提供了一个sp地址的命名名称, 如?ID?MEASURE,以便可以让最终用户在连接时由 linker 为?ID?MEASURE确定地址 。模块结构大致如下:
?ID?MEASURE segment idata
rseg ?ID?MEASURE
ds 1
…
mov SP, #?ID?MEASURE
Linker 在连接时,可以自动也可以手工用 stack参数设定?ID?MEASURE的具体位置, 并可以保留若干字节(8086 汇编里经常有这种需求,为了不污染原来的stack). 这种 sp 被更改所产生的数据区域, 徐爱钧的书以及 keil 称为栈段(stack segment), 没有称为 "模块私有栈".
因此, 只要模块中没有设置 sp, 那么就不会有stack segment, 也就是冷漠所说的“模块私有栈".
而 ?stack 仅仅是一个命名名称,作用是在startup 初始化sp,即:
mov sp, #?stack - 1
?stack 的值在连接时确定, 此外,别无特殊意义。当在某个模块里重设sp 后,其后所有的栈活动(call, interrupt, push, pop,ret,reti)都会从新栈点开始。
.
.
.
结论:
a) 如果程序中, 用户没有重新设置 sp, 而且排除另一个概念---计算机软件算法中的栈, 那么
*) 不存在所谓的“模块私有栈“, 不论有多少模块
*)只有一个涉及sp 的栈,没有其他的乱七八糟的栈
b) 如果程序员在程序中多次设置 sp, 这些sp的活动数据区被称为 stack segment, 而不是一个独立的“stack"
如果对上述内容不能理解,请仔细阅读链接中的内容
http://www.keil.com/support/man/docs/bl51/bl51_stack.htm |