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

Ben*_*tto 87 architecture stack history

我知道在我个人熟悉的架构(x86,6502等)中,堆栈通常会向下增长(即,每个推入堆栈的项目都会导致SP递减,而不是递增的SP).

我想知道这个的历史原因.我知道在一个统一的地址空间中,在数据段的另一端(例如)开始堆栈很方便,所以如果双方在中间发生碰撞,那么只会出现问题.但是为什么堆栈传统上是最重要的?特别是考虑到这与"概念"模型的对立面如何?

(请注意,在6502架构中,堆栈也向下增长,即使它被限制在一个256字节的页面上,这个方向选择似乎是任意的.)

pax*_*blo 47

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

另外,请注意,所有早期CPU 的程序计数器设置为0时的设置不是这种情况.例如,摩托罗拉6809将从地址获取程序计数器,0xfffe/f因此您可以开始在任意位置运行,具体取决于该地址提供的内容(通常,但不限于ROM).

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

关于堆栈增长,并非所有堆栈都向下增长,请参阅此答案以获取详细信息.


anq*_*anq 21

我听到的一个很好的解释是,过去的某些机器只能有无符号偏移量,所以你希望堆栈向下增长,这样你就可以击中当地人,而不必丢失额外的指令来伪造负偏移量.


roo*_*ebo 10

Stanley Mazor(4004 和 8080 架构师)在“英特尔微处理器:8008 到 8086”中解释了如何为 8080(最终为 8086)选择堆栈增长方向:

堆栈指针被选择为“下坡”运行(堆栈向较低的内存前进)以简化从用户程序(正索引)到堆栈的索引并简化从前面板显示堆栈的内容。


jal*_*alf 6

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

  • @jww - 这是一个没有区别的区别。我可能会声称计算机的不加他们只减!就这个答案而言,这并不重要 - 但大多数 ALU 将使用支持加法和减法的 [电路](https://en.wikipedia.org/wiki/Adder%E2%80%93subtractor)具有相同的性能。也就是说,虽然`A - B` 可以在概念上实现为`A + (-B)`(即`B` 的单独否定步骤),但实际上并非如此。 (3认同)
  • @jww 对于早期的计算机来说,你的挑剔是错误的 - 二进制补码获胜需要一些时间,直到它获胜之前,有些计算机使用补码和符号和幅度,也许还有其他东西。通过这些实现,加法与减法相比可能更有优势。因此,在缺乏附加信息的情况下,将其排除为影响寻址方案选择(如堆栈方向)的可能因素是错误的。 (2认同)

DrS*_*don 5

因为 aPOP使用与通常用于扫描字符串和数组相同的寻址模式

从堆栈中弹出值的指令需要执行两件事:从内存中读取值并调整堆栈指针。此操作有四种可能的设计选择:

  1. 先预增堆栈指针,然后读取值。这意味着堆栈将“向下”增长(朝向较低的内存地址)。

  2. 先预减堆栈指针,然后读取值。这意味着堆栈将“向上”增长(朝向更高的内存地址)。

  3. 先读取值,然后后递增堆栈指针。这意味着堆栈将向下增长。

  4. 首先读取值,然后对堆栈指针进行后递减。这意味着堆栈将向上增长。


在许多计算机语言(特别是 C)中,字符串和数组作为指向其第一个元素的指针传递给函数。一个非常常见的操作是从第一个元素开始按顺序读取字符串或数组的元素。这样的操作只需要上述的后递增寻址方式。

此外,读取字符串或数组的元素比写入元素更常见。事实上,有许多标准库函数根本不执行任何写入操作(例如,,,strlen())!strchr()strcmp()


因此,如果指令集设计中的寻址模式数量有限,则最有用的寻址模式将是后增量读取。这不仅产生了最有用的字符串和数组操作,而且产生了使堆栈向下增长的POP指令。

第二个最有用的寻址模式是后递减写入,可用于匹配PUSH指令。

事实上,PDP-11 具有后递增和前递减寻址模式,这产生了向下增长的堆栈。甚至VAX也没有预增量或后减量。