C++ 堆栈上的内存分配和缓冲区溢出,x86 ISA32

C++ 堆栈上的内存分配和缓冲区溢出,x86 ISA32,c++,c,memory-management,x86,C++,C,Memory Management,X86,因此,我一直在学习缓冲区溢出以及将内存保存到堆栈上的过程,但我不理解某些约定。保存局部变量/数组时,为什么要将内存从堆栈指针分配到基指针 (数组[0]将更接近堆栈顶部,数组[1]到数组[n-1]将更接近帧的基指针) 为什么不换个方向呢?如果将数组[n-1]分配给堆栈指针,则上一帧中保存的寄存器/返回地址不会受到威胁 我读过wiki文章和stacks that grow up一节,但是他们假设在分配缓冲区之前返回地址就在那里,这意味着缓冲区会覆盖返回。但这不应该是另一种方式吗?返回地址不应该只在声

因此,我一直在学习缓冲区溢出以及将内存保存到堆栈上的过程,但我不理解某些约定。保存局部变量/数组时,为什么要将内存从堆栈指针分配到基指针

(数组[0]将更接近堆栈顶部,数组[1]到数组[n-1]将更接近帧的基指针)

为什么不换个方向呢?如果将数组[n-1]分配给堆栈指针,则上一帧中保存的寄存器/返回地址不会受到威胁


我读过wiki文章和stacks that grow up一节,但是他们假设在分配缓冲区之前返回地址就在那里,这意味着缓冲区会覆盖返回。但这不应该是另一种方式吗?返回地址不应该只在声明局部变量后写入堆栈吗?

历史上,堆栈和堆占用相同的内存空间。堆是从底部分配的,而堆栈是从顶部分配的。当你溢出。。。您只需覆盖其他空间内存,很快就会导致崩溃

我相信,现在已经不是这样了,但用于管理堆栈的x86指令集仍然存在,因此它从顶部消耗内存


但是数组是从底部索引的。由于这个原因,
array[0]
更接近堆栈的“顶部”(在下面),而
array[n-1]
则更远。

x86体系结构受到Intel 8080的严重影响,Intel 8080具有类似的堆栈体系结构(一个共享调用和向下增长的数据堆栈)。当时,这被视为一个重大进步,因为8080的前身8008有一个内置在CPU中的调用堆栈,只有七层深

英特尔8080于1974年发布。考虑到网络化的东西不多(例如,以太网刚刚开发出来),潜在的堆栈破坏攻击可能不是主要问题。另一方面,灵活性和充分利用可用的RAM是非常重要的


很久以后,堆叠粉碎成为一个主要问题。例如,1996年发布了。

x86堆栈向下扩展,而不是向上扩展。因为这样可以减少内存浪费:如果堆栈和堆使用相同的(64k)段,那么这两个堆栈将朝着另一个方向扩展。根据需要,中间的空间可用于堆栈或堆。如果向上扩展,则有两个空格,您必须提前决定为堆栈保留哪些内存,为堆保留哪些内存。这只是因为大多数计算机语言要求数组元素0驻留在比元素1更小的地址中。