我正在准备一些 C 语言培训 Material ,我希望我的示例适合典型的堆栈模型。
C 堆栈在 Linux、Windows、Mac OSX(PPC 和 x86)、Solaris 和最新的 Unix 中朝什么方向发展?
最佳答案
堆栈增长通常并不取决于操作系统本身,而是取决于其运行的处理器。例如,Solaris 在 x86 和 SPARC 上运行。 Mac OSX(正如您所提到的)在 PPC 和 x86 上运行。 Linux 可以运行在从我工作中的 System z 到 puny little wristwatch 的所有东西上。
如果 CPU 提供任何类型的选择,那么如果您希望自己的代码调用其他人的代码,则操作系统使用的 ABI/调用约定会指定您需要做出的选择。
处理器及其方向是:
- x86:向下。
- SPARC:可选。标准 ABI 使用羽绒。
- PPC:我认为下降了。
- System z:在一个链接列表中,我没有骗你(但仍然处于关闭状态,至少对于 zLinux 而言)。
- ARM:可选,但 Thumb2 仅具有向下的紧凑编码(LDMIA = 之后递增,STMDB = 之前递减)。
- 6502:向下(但只有 256 字节)。
- RCA 1802A:您想要的任何方式,均以 SCRT 实现为准。
- PDP11:下降。
- 8051:向上。
最后几台显示了我的年龄,1802 是用于控制早期航天飞机的芯片(我怀疑,根据它的处理能力来感应门是否打开:-) 和我的第二台计算机,COMX-35 (跟随我的 ZX80 )。
从 here 收集 PDP11 详细信息,从 here 收集 8051 详细信息。
SPARC架构采用滑动窗口寄存器模型。架构上可见的细节还包括寄存器窗口的循环缓冲区,该缓冲区有效并在内部缓存,在上溢/下溢时带有陷阱。详细信息请参见 here。如 the SPARCv8 manual explains , SAVE 和 RESTORE 指令就像 ADD 指令加上寄存器窗口旋转。使用正常量而不是通常的负常量将产生向上增长的堆栈。
前面提到的 SCRT 技术是另一种 - 1802 使用一些或十六个 16 位寄存器用于 SCRT(标准调用和返回技术)。一是程序计数器,您可以使用SEP Rn
指令将任何寄存器用作PC。一个是堆栈指针,两个总是指向 SCRT 代码地址,一个用于调用,一个用于返回。 没有寄存器以特殊方式处理。请记住,这些细节来自内存,它们可能不完全正确。
例如,如果 R3 是 PC,R4 是 SCRT 调用地址,R5 是 SCRT 返回地址,R2 是“堆栈”(在软件中实现时引用),SEP R4
会将 R4 设置为 PC 并开始运行 SCRT 调用代码。
然后它将把 R3 存储在 R2“堆栈”上(我认为 R6 用于临时存储),向上或向下调整它,抓取 R3 后面的两个字节,将它们加载到 R3 中,然后执行 SEP R3
并在新地址运行。
要返回,它将SEP R5
从R2堆栈中拉出旧地址,向其添加两个(以跳过调用的地址字节),将其加载到R3和SEP R3
开始运行之前的代码。
在所有基于 6502/6809/z80 堆栈的代码之后,一开始很难理解,但仍然以一种令人头晕目眩的方式优雅。该芯片的一大卖点是全套 16 个 16 位寄存器,尽管您立即丢失了其中 7 个(5 个用于 SCRT,两个用于 DMA 和内存中断)。啊,营销战胜现实:-)
System z 实际上非常相似,使用其 R14 和 R15 寄存器进行调用/返回。
关于assembly - 大多数现代系统中堆栈增长的方向是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/664744/