栈的方向,是一个内存布局问题。在现代向上和向下架构上没有优劣。
早期的系统需要考虑有限内存下的内存布局问题。具体来说,内存的一端放置了静态代码和静态数据之后,剩余的区域,既需要动态数据,又需要可增长的栈,那么合理的方案就是各放一端向中间生长。现在的问题就是两个选项:静态内存放在哪端;栈是在静态内存的同端还是对端。
考虑下面的一些条件:
- 早期的部分机器,从0地址启动[1]。想象一下磁带机的编址。
- 动态数据从概念上来说,和静态数据比较像
所以从内存布局来说,一个自然的方案是,从0地址依次放置代码、静态数据、动态数据,高地址放置栈。
------------------------------------------------------------------------------------
在很早的时候,intel计算机内存就是分了代码段和栈空间区域的。
程序计数器(Program Counter)的缺省指向0地址,计算机开机后从程序计数器指向的地址开始执行程序,每执行完一条指令后, 程序计数器自动加1。
因此很自然的,代码段从低地址区间开始加载,向高地址区间扩展;为了避免栈空间和代码段冲突,最大利用地址空间,很自然的,我们会选择把栈底设置在高地址区间,然后让栈向下增长。
这是来自apue里一张经典的c程序内存分布图
然而,从安全性来说,向低地址扩展也有微弱劣势:
- 数组、字符串越界时会覆盖过去栈帧的数据,黑客更容易找到缓冲区溢出攻击的漏洞。