为什么堆栈通常会向下扩展?
我知道,在我个人熟悉的架构(x86,6502等)中,堆栈通常会向下增长(即每个物品被压入堆栈导致递减的SP,而不是递增的)。
我想知道这个历史的理由。 我知道在一个统一的地址空间中,在数据段的另一端(比如说)启动堆栈是很方便的,所以如果双方在中间相互碰撞只会有问题。 但是,为什么堆栈传统上得到顶部? 特别是考虑到这与“概念”模式相反吗?
(请注意,在6502架构中,堆栈也向下增长,即使它被限制在一个256字节的页面上,这个方向的select似乎是任意的)。
至于历史的理由,我不能肯定地说(因为我没有devise它们)。 我的想法是,早期的CPU把他们原来的程序计数器设置为0,这是自然而然的愿望,在另一端启动堆栈并向下扩展,因为它们的代码自然会向上增长。
顺便说一下,请注意,复位时程序计数器的这个设置不是所有早期CPU的情况。 例如,Motorola 6809将从地址
0xfffe/f
获取程序计数器,以便您可以在任意位置开始运行,具体取决于在该地址提供的内容(通常但不限于ROM)。
一些历史系统可能会做的第一件事情是从顶部扫描存储器,直到find一个可以读取相同值的位置,以便它知道安装的实际RAM(例如,具有64K地址空间的z80不一定有64K或内存,实际上64K在我的早期将是巨大的 )。 一旦find最上面的实际地址,就会正确设置堆栈指针,然后开始调用子程序。 这种扫描通常由CPU在ROM中作为启动的一部分运行代码完成。
关于堆栈的增长,并不是所有的都在向下发展,请看这个答案的细节。
我听到的一个很好的解释是,过去的一些机器只能使用无符号偏移量,所以你希望堆栈向下增长,这样你就可以打到你的本地机器上,而不必失去额外的指令来伪造一个负偏移量。
一个可能的原因可能是它简化了alignment。 如果将一个局部variables放在必须放置在一个4字节边界上的堆栈中,则可以简单地从堆栈指针中减去该对象的大小,然后将两个较低位清零以获得正确alignment的地址。 如果堆栈向上增长,确保alignment变得有点棘手。
IIRC堆栈向下生长,因为堆堆向上生长。 这可能是相反的。
我相信这完全是一个devise决定。 并不是所有的系统都向下发展 – 请参阅这个线索,以便在不同架构上讨论堆栈增长的方向。
我相信这个惯例始于IBM 704及其臭名昭着的“减量登记册”。 现代的讲话会把它称为教学的一个抵消领域,但重点是他们去了 , 而不是 起来 。
我不确定,但是我在当时做了一些VAX / VMS的编程。 我似乎记得一部分内存(堆)上升和堆栈下降。 当两人见面的时候,你已经记不起了。