堆栈增长通常并不取决于操作系统本身,而是取决于其运行的处理器。例如,Solaris 在 x86 和 SPARC 上运行。 Mac OSX(正如您所提到的)在 PPC 和 x86 上运行。 Linux 可以在一切上运行,从工作中的 System z 到微不足道的小手表 http://web.archive.org/web/20090322124254/http://www.research.ibm.com/WearableComputing/linuxwatch/linuxwatch.html.
如果 CPU 提供任何类型的选择,那么如果您希望自己的代码调用其他人的代码,则操作系统使用的 ABI/调用约定会指定您需要做出的选择。
处理器及其方向是:
- x86:向下。
- SPARC:可选。标准 ABI 使用羽绒。
- PPC:我认为下降了。
- System z:在一个链表中,我没有骗你(但仍然失败,至少对于 zLinux 来说)。
- ARM:可选,但 Thumb2 仅具有向下的紧凑编码(LDMIA = 之后递增,STMDB = 之前递减)。
- 6502:向下(但只有256字节)。
- RCA 1802A:任何你想要的方式,服从 SCRT 实施。
- PDP11:下。
- 8051:上。
最后几台显示了我的年龄,1802 是用于控制早期航天飞机的芯片(我怀疑,根据它的处理能力来感应门是否打开:-),以及我的第二台计算机,COMX-35 http://en.wikipedia.org/wiki/Comx-35(按照我的ZX80 http://en.wikipedia.org/wiki/Zx80).
PDP11 详细信息收集自here http://en.wikipedia.org/wiki/PDP-11_architecture, 8051 详情来自here http://what-when-how.com/8051-microcontroller/8051-register-banks-and-stack/.
SPARC架构使用滑动窗口寄存器模型。架构上可见的细节还包括寄存器窗口的循环缓冲区,该缓冲区有效并在内部缓存,在上溢/下溢时带有陷阱。看here http://icps.u-strasbg.fr/people/loechner/public_html/enseignement/SPARC/sparcstack.html了解详情。作为SPARCv8 手册说明 http://www.gaisler.com/doc/sparcv8.pdf#page=53、SAVE 和 RESTORE 指令类似于 ADD 指令加上寄存器窗口旋转。使用正常数而不是通常的负常数将产生向上增长的堆栈。
上述 SCRT 技术是另一种技术 - 1802 使用一些或十六个 16 位寄存器进行 SCRT(标准调用和返回技术)。一个是程序计数器,你可以使用任何寄存器作为PC机SEP Rn
操作说明。一个是堆栈指针,两个总是指向 SCRT 代码地址,一个用于调用,一个用于返回。No寄存器以特殊方式处理。请记住,这些细节来自记忆,它们可能不完全正确。
例如,如果 R3 是 PC,R4 是 SCRT 调用地址,R5 是 SCRT 返回地址,R2 是“堆栈”(在软件中实现时引用),SEP R4
会将 R4 设置为 PC 并开始运行 SCRT 调用代码。
然后它将R3存储在R2“堆栈”上(我认为R6用于临时存储),向上或向下调整它,抓取R3后面的两个字节,加载它们intoR3,然后做SEP R3
并在新地址运行。
要返回,它会SEP R5
这会将旧地址从 R2 堆栈中拉出,向其添加两个(以跳过调用的地址字节),将其加载到 R3 中并SEP R3
开始运行前面的代码。
在完成所有基于 6502/6809/z80 堆栈的代码之后,一开始很难理解,但仍然以一种令人头晕目眩的方式优雅。此外,该芯片的一大卖点是全套 16 个 16 位寄存器,尽管您立即丢失了其中 7 个(5 个用于 SCRT,两个用于 DMA 和内存中断)。啊,营销战胜现实:-)
System z 实际上非常相似,使用其 R14 和 R15 寄存器进行调用/返回。