3 回答
TA贡献1853条经验 获得超9个赞
至于历史的基本原理,我不能确定地说(因为我没有设计它们)。我对此的想法是,早期的CPU会将其原始程序计数器设置为0,并且很自然地希望在另一端启动堆栈并向下扩展,因为它们的代码自然会向上扩展。
另外,请注意,并非所有早期的CPU 都将复位时将程序计数器设置为0 。例如,Motorola 6809将从地址中读取程序计数器,0xfffe/f以便您可以在任意位置开始运行,具体取决于该地址提供的内容(通常但绝不限于ROM)。
历史系统将要做的第一件事是从顶部开始扫描内存,直到找到一个位置,该位置将回读相同的写入值,以便它知道实际安装的RAM(例如,具有64K地址空间的z80不一定有64K或RAM,实际上64K 在我早期很庞大。一旦找到最上面的实际地址,它将适当地设置堆栈指针,然后可以开始调用子例程。作为启动的一部分,这种扫描通常由ROM中的CPU运行代码完成。
TA贡献1851条经验 获得超4个赞
一个可能的原因可能是它简化了对齐。如果在堆栈上放置一个必须放在4字节边界上的局部变量,则可以简单地从堆栈指针中减去对象的大小,然后将两个低位清零以获得正确对齐的地址。如果堆栈向上生长,则确保对齐变得有些棘手。
TA贡献2011条经验 获得超2个赞
再加2分:
除了提到的所有历史依据外,我敢肯定,没有理由在现代处理器中是有效的。所有处理器都可以采用带符号的偏移量,并且自从我们开始处理多个线程以来,最大程度地提高堆/堆栈距离就没有什么意义。
我个人认为这是安全设计缺陷。如果说x64体系结构的设计者会改变堆栈的增长方向,那么大多数堆栈缓冲区溢出将被消除-这是很大的事情。(因为琴弦向上生长)。
添加回答
举报