一个比较幼稚的问题:栈上内存分配的方向

时间:2020-12-04 02:23:54
为何栈上内存的分配都是从高到低?即栈的增长方向为何从大到小??(这是人为规定,还是有讲究的)
如:
...
int i=0;
int j=0;
...
32位系统下
如果&i=FFFFF4,那么&j=FFFF0(呵呵,只是举例,没有实际根据)

24 个解决方案

#1


不好意思更正一下
...
如果&i=FFFFFFF4,那么&j=FFFFFFF0

#2


在X86体系中,栈是向下生长的,入栈指令将使栈指针向向下,而出栈将使栈指针增长,当然你可以构造非系统堆栈,它不受出入栈影响,你可以自行规定向上或向下增长,不过一般都遵循系统的默认规范。而且这样设置是有道理的,因为栈其实是可以无限增长的,除非你自行检查,不然不会发现栈溢出,所以数据区,代码区都是由下向上执行的,而堆栈是由上向下增长的,向对开的列车,留下了充分的空间,减少了相遇的可能。

#3


就是这么规定的

#4


我看从大到小,从小到大都没什么本质区别,应该是规定吧?

#5


你就记得得了,哪来这么多问题。

#6


to glassshark(glassshark) 
windows上堆地址大于栈地址,堆和栈相背发展。作何解释?

#7


这是一个implementation-define的东东,不同的平台下面的做法不一定相同

#8


up

#9


系统分配堆栈是有一定大小限制的,所以上下并不重要.

#10


》》windows上堆地址大于栈地址,堆和栈相背发展。作何解释?
虚地址,并非物理内存地址,未必是真正的大于,背对背更安全,不容易互相覆盖,防止下溢即可。

#11


从8086继承而来。

#12


KissCpp:看了这么多人的回答,我都不是十分认同。

#13


glassshark说的是有道理的,栈的增长方向是有CPU的硬件决定的,PUSH指令就是使堆栈指针减4。

#14


栈的增长方向是有CPU的硬件决定的,x86商战的增长方向是有高地址到低地址
你不妨看看vc里的汇编代码,以及mem窗口就知道了。

#15


cpu硬件决定!没什么好讲的!

#16


cpu硬件决定,有的risc cpu就是上增长的

#17


硬件还不是由人规定的

#18


没什么讲究,就是人为规定的。
同样是intel出的cpu,象51系列栈就是向上增长的
不过我同意glassshark(glassshark) 的看法
栈和数据定义如果方向相反的话要方便一点
这一点在做51编程的时候有亲自感受,
51的片内内存本来就很小,就感觉不好安排,再加上你定义的数据只能从低到高定义(当然,你硬性指定高地址位也可以,但是这样就失去了灵活性)对栈初值的选择就有点麻烦。
所以做51的程序时就在想,为什么它不象X86系列这样栈从高到低啊

#19


up you.

#20


cpu的sp指针在程序载入时,值最大(即栈顶),用减法来移动堆栈指针,可以防止越界(毕竟加法可以一直加,直到寄存器到顶,可是堆栈没有那么大)

#21


呵呵,谢谢各位的解释。小弟之所以问这个可能比较幼稚的问题,主要是
最近学c发现一个有意思的问题如下:
...
int i=0;
char a[]="imisshua";
int j=0;
...

发现它的内存分配顺序为:
i
a[8]
a[7]
...
..
a[1]
a[0]
j

而不是我当时认为的:
i
a[0]
a[1]
...
..
a[7]
a[8]
j
和同学讨论,大家觉得可能是因为为了&a[0]<&a[1]<...<&a[8],这样当char*p=a;p++会指到a[1],比较符合习惯。
(如果大家有更好的解释,请就贴到这!)但又细想后觉得,如果栈本身从低到高分配,分配顺序还为
i
a[0]
a[1]
...
..
a[7]
a[8]
j
那么既&a[0]<&a[1]<...<&a[8],又char*p=a;p++会指到a[1],不更符合习惯思维吗??
所以就有了这个比较幼稚的问题!

#22


up you.

#23


你也可以定义堆栈向高地址增长,但是C好象不可以

#24


up me

#1


不好意思更正一下
...
如果&i=FFFFFFF4,那么&j=FFFFFFF0

#2


在X86体系中,栈是向下生长的,入栈指令将使栈指针向向下,而出栈将使栈指针增长,当然你可以构造非系统堆栈,它不受出入栈影响,你可以自行规定向上或向下增长,不过一般都遵循系统的默认规范。而且这样设置是有道理的,因为栈其实是可以无限增长的,除非你自行检查,不然不会发现栈溢出,所以数据区,代码区都是由下向上执行的,而堆栈是由上向下增长的,向对开的列车,留下了充分的空间,减少了相遇的可能。

#3


就是这么规定的

#4


我看从大到小,从小到大都没什么本质区别,应该是规定吧?

#5


你就记得得了,哪来这么多问题。

#6


to glassshark(glassshark) 
windows上堆地址大于栈地址,堆和栈相背发展。作何解释?

#7


这是一个implementation-define的东东,不同的平台下面的做法不一定相同

#8


up

#9


系统分配堆栈是有一定大小限制的,所以上下并不重要.

#10


》》windows上堆地址大于栈地址,堆和栈相背发展。作何解释?
虚地址,并非物理内存地址,未必是真正的大于,背对背更安全,不容易互相覆盖,防止下溢即可。

#11


从8086继承而来。

#12


KissCpp:看了这么多人的回答,我都不是十分认同。

#13


glassshark说的是有道理的,栈的增长方向是有CPU的硬件决定的,PUSH指令就是使堆栈指针减4。

#14


栈的增长方向是有CPU的硬件决定的,x86商战的增长方向是有高地址到低地址
你不妨看看vc里的汇编代码,以及mem窗口就知道了。

#15


cpu硬件决定!没什么好讲的!

#16


cpu硬件决定,有的risc cpu就是上增长的

#17


硬件还不是由人规定的

#18


没什么讲究,就是人为规定的。
同样是intel出的cpu,象51系列栈就是向上增长的
不过我同意glassshark(glassshark) 的看法
栈和数据定义如果方向相反的话要方便一点
这一点在做51编程的时候有亲自感受,
51的片内内存本来就很小,就感觉不好安排,再加上你定义的数据只能从低到高定义(当然,你硬性指定高地址位也可以,但是这样就失去了灵活性)对栈初值的选择就有点麻烦。
所以做51的程序时就在想,为什么它不象X86系列这样栈从高到低啊

#19


up you.

#20


cpu的sp指针在程序载入时,值最大(即栈顶),用减法来移动堆栈指针,可以防止越界(毕竟加法可以一直加,直到寄存器到顶,可是堆栈没有那么大)

#21


呵呵,谢谢各位的解释。小弟之所以问这个可能比较幼稚的问题,主要是
最近学c发现一个有意思的问题如下:
...
int i=0;
char a[]="imisshua";
int j=0;
...

发现它的内存分配顺序为:
i
a[8]
a[7]
...
..
a[1]
a[0]
j

而不是我当时认为的:
i
a[0]
a[1]
...
..
a[7]
a[8]
j
和同学讨论,大家觉得可能是因为为了&a[0]<&a[1]<...<&a[8],这样当char*p=a;p++会指到a[1],比较符合习惯。
(如果大家有更好的解释,请就贴到这!)但又细想后觉得,如果栈本身从低到高分配,分配顺序还为
i
a[0]
a[1]
...
..
a[7]
a[8]
j
那么既&a[0]<&a[1]<...<&a[8],又char*p=a;p++会指到a[1],不更符合习惯思维吗??
所以就有了这个比较幼稚的问题!

#22


up you.

#23


你也可以定义堆栈向高地址增长,但是C好象不可以

#24


up me