我正在准备一些用C编写的培训资料,我希望我的示例适合典型的堆栈模型。
在Linux,Windows,Mac OSX(PPC和x86),Solaris和最新的Unix中,C堆栈会朝哪个方向发展?
最佳答案
堆栈的增长通常不取决于操作系统本身,而是取决于它所运行的处理器。例如,Solaris在x86和SPARC上运行。如前所述,Mac OSX在PPC和x86上运行。 Linux可以运行在从我工作的大型System z到puny little wristwatch的所有内容上。
如果CPU提供任何选择,则操作系统要使用的ABI /调用约定指定了您希望代码调用其他所有人的代码时需要做出的选择。
处理器及其方向是:
在最后几年显示我的年龄,1802是用来控制早期航天飞机的芯片(基于其具有的处理能力,我怀疑门是否打开了:-)和第二台计算机COMX-35(跟随我ZX80)。
PDP11详细信息从here中收集,8051详细信息从here中收集。
SPARC体系结构使用滑动窗口寄存器模型。在体系结构上可见的细节还包括寄存器窗口的循环缓冲区,该缓冲区有效并在内部缓存,并且在上溢/下溢时会出现陷阱。有关详细信息,请参见here。与the SPARCv8 manual explains一样,SAVE和RESTORE指令类似于ADD指令加上寄存器窗口旋转。使用正常数而不是通常的负数将使堆栈向上增长。
前面提到的SCRT技术是另一种-1802使用了一部分或16个16位寄存器用于SCRT(标准调用和返回技术)。其中一个是程序计数器,您可以使用
SEP Rn
指令将任何寄存器用作PC。一个是堆栈指针,两个始终设置为指向SCRT代码地址,一个用于调用,一个用于返回。没有对寄存器进行特殊处理。请记住,这些细节来自内存,它们可能并不完全正确。例如,如果R3是PC,R4是SCRT调用地址,R5是SCRT返回地址,R2是“堆栈”(引用是在软件中实现的),则
SEP R4
会将R4设置为PC并开始运行SCRT call 代码。然后它将R3存储在R2“堆栈”上(我认为R6用于临时存储),向上或向下调整,获取R3之后的两个字节,将它们加载到R3中,然后执行
SEP R3
并在新地址上运行。要返回,将使用
SEP R5
将旧地址从R2堆栈中拉出,向其添加两个地址(以跳过调用的地址字节),将其加载到R3和SEP R3
中以开始运行先前的代码。最初,在完成所有基于6502/6809 / z80堆栈的代码之后,很难将头缠绕起来,但是仍然以一种“碰头撞墙”的方式保持优雅。该芯片的最大卖点之一是全套的16个16位寄存器,尽管事实上您立即丢失了其中的7个(5个用于SCRT,两个用于DMA和内存中断)。啊,营销胜过现实:-)
系统z实际上非常相似,使用其R14和R15寄存器进行 call /返回。
关于assembly - 在大多数现代系统中,堆栈增长的方向是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/664744/