程序堆栈的增长方向究竟是什么?

时间:2013-12-08 11:23:18

标签: linux assembly linux-kernel x86 stack

我正在阅读理查德·布鲁姆的专业汇编语言,我对书中的不一致感到困惑,我想知道程序堆栈的增长方向究竟是什么? 这是第312页的图片,表明程序堆栈已经成长。

enter image description here

但是当我到达第322页时,我看到了另一个版本,这表明程序堆栈会逐渐减少。 enter image description here

和这个

enter image description here

4 个答案:

答案 0 :(得分:4)

这本书并不矛盾;每张图在顶部显示更高的地址。

第一张图说明了向下增长的堆栈。调用者将参数压入堆栈,然后调用新函数。调用行为将返回地址压入堆栈。然后被调用者将基指针的当前值压入堆栈,将堆栈指针复制到基指针中,并递减堆栈指针以为被调用者的局部变量腾出空间。

答案 1 :(得分:0)

堆栈增长方向因操作系统,CPU架构以及其他许多因素而异。

最常见的布局是堆栈从内存顶部开始并向下扩展,而堆从底部开始并逐渐增长。有时它是另一种方式,例如。 OSX之前的MacOS将堆栈放在代码区域之上,随着堆积的增长,堆积从内存顶部开始逐渐增长。

答案 2 :(得分:0)

一些背景知识:

对于不同的处理器,堆栈指针的含义和堆栈的方向可能不同。对于TMS Piccolo控制器堆栈正在成长,因此“PUSH”将增加堆栈指针。堆栈指针可以指向最后推送的值或指向要写入下一个值的位置。 ARM处理器允许堆栈的所有4种可能的组合,因此必须有关于如何使用堆栈指针的约定。

在x86处理器上:

在x86处理器堆栈上总是向下增长,因此“PUSH”指令会减少堆栈指针;堆栈指针始终指向最后推送的值。

第一张图片显示堆栈指针(地址>堆栈指针)之后的地址已包含值。如果将更多值存储到堆栈,它们将存储到堆栈指针下方的位置(下一个值将存储到地址-16(%ebp))。这意味着来自页面312的图片也显示了一个向下增长的堆栈。

- 编辑 -

如果处理器有“PUSH”指令,则堆栈增长的方向由CPU给出。对于没有“PUSH”指令的CPU(如PowerPC或没有ARM-THUMB代码的ARM),操作系统必须定义堆栈增长的方向。

答案 3 :(得分:0)

更引人注目的堆栈增长方向定义是(如果处理器有)中断堆栈。一些架构(如PowerPC)根本没有硬件堆栈。然后系统设计人员可以决定实现堆栈的方式:预递增,后递增。预先递减或后递减。

在PPC中,调用使用链接寄存器,如果没有以编程方式保存返回地址,则下一次调用将覆盖它。

PPC中断使用2个特殊寄存器 - “返回地址”和机器状态。那是因为中断后可以“重启”指令 - 一种处理流水线架构中的中断的方法。

预增量:堆栈指针在存储之前递增 - 堆栈指针指向最后使用的项目。看到几个更奇怪的8位架构(一些第四处理器等)。

后递增:存储在堆栈指针递增之前完成 - 堆栈指针指向第一个自由堆栈元素。

减量前后:与上述类似,但堆栈向下增长(更常见)。

最常见的是后递减。