为了账号安全,请及时绑定邮箱和手机立即绑定

为什么堆栈通常会向下生长?

为什么堆栈通常会向下生长?

富国沪深 2019-10-26 13:34:08
我知道在我个人熟悉的体系结构(x86、6502等)中,堆栈通常会向下增长(即,推入堆栈的每个项目都会导致SP递减,而不是递增的SP)。我想知道这样做的历史依据。我知道,在统一的地址空间中,在数据段的另一端启动堆栈很方便(例如),因此,如果两侧在中间碰撞,则只会有问题。但是,为什么传统上堆栈会占据顶部呢?特别是考虑到这与“概念”模型相反的情况?(请注意,在6502架构中,即使堆栈绑定到单个256字节的页面,堆栈也向下增长,并且这种方向选择似乎是任意的。)
查看完整描述

3 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

至于历史的基本原理,我不能确定地说(因为我没有设计它们)。我对此的想法是,早期的CPU会将其原始程序计数器设置为0,并且很自然地希望在另一端启动堆栈并向下扩展,因为它们的代码自然会向上扩展。


另外,请注意,并非所有早期的CPU 都将复位时将程序计数器设置为0 。例如,Motorola 6809将从地址中读取程序计数器,0xfffe/f以便您可以在任意位置开始运行,具体取决于该地址提供的内容(通常但绝不限于ROM)。


历史系统将要做的第一件事是从顶部开始扫描内存,直到找到一个位置,该位置将回读相同的写入值,以便它知道实际安装的RAM(例如,具有64K地址空间的z80不一定有64K或RAM,实际上64K 在我早期很庞大。一旦找到最上面的实际地址,它将适当地设置堆栈指针,然后可以开始调用子例程。作为启动的一部分,这种扫描通常由ROM中的CPU运行代码完成。


查看完整回答
反对 回复 2019-10-26
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

一个可能的原因可能是它简化了对齐。如果在堆栈上放置一个必须放在4字节边界上的局部变量,则可以简单地从堆栈指针中减去对象的大小,然后将两个低位清零以获得正确对齐的地址。如果堆栈向上生长,则确保对齐变得有些棘手。


查看完整回答
反对 回复 2019-10-26
?
森林海

TA贡献2011条经验 获得超2个赞

再加2分:

除了提到的所有历史依据外,我敢肯定,没有理由在现代处理器中是有效的。所有处理器都可以采用带符号的偏移量,并且自从我们开始处理多个线程以来,最大程度地提高堆/堆栈距离就没有什么意义。

我个人认为这是安全设计缺陷。如果说x64体系结构的设计者会改变堆栈的增长方向,那么大多数堆栈缓冲区溢出将被消除-这是很大的事情。(因为琴弦向上生长)。


查看完整回答
反对 回复 2019-10-26
  • 3 回答
  • 0 关注
  • 1269 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信