栈生长方向的定义与CPU的栈生长方向

栈的生长方向理解

栈生长方向指的就是执行push、pop命令后,堆栈指针ps所指向的地址是增大还是减小,

栈向上生长:执行push指令后ps所指地址增大;

栈向下生长:执行push指令后ps所指地址减小;



51的栈是向高地址增长INTEL8031803280488051系列使用向高地址增长堆栈;但同样是INTEL,在x86系列中全部使用向低地址增长堆栈。其他公司的CPU中除ARM的结构提供向高地址增长堆栈选项外,多数都是使用向低地址增长堆栈


在没有MMU的时代,为了最大的利用内存空间,堆和栈被设计为从两端相向生长。那么哪一个向上,哪一个向下呢?
  人们对数据访问是习惯于向上的,比如你在堆中new一个数组,是习惯于把低元素放到低地址,把高位放到高地址,所以堆向上生长比较符合习惯。而栈则对方向不敏感,一般对栈的操作只有PUSH和pop,无所谓向上向下,所以就把堆放在了低端,把栈放在了高端。MMU出来后就无所谓了,只不过也没必要改了。
  51这种单片机,没有堆,只有栈,所以把栈设计成向上,有利于扩展,比如52在127后面加个128个字节,程序就不必修改可以直接移植,如果是向下的话要利用这多出来的128字节就要修改程序,改变堆栈指针了。


PS:数据间的地址高低看cpu的体系,一般是固定的。数据内的地址高低看cpu的大小端模式,有时可以改的。


ARM 同时支持这两种增长方式,向上生长和向下生长。 对于向上生长,在向堆栈写入数据后,堆栈指针的值变大,称之为递增堆栈。 反之为递减堆栈。


另外需要注意的一点是堆栈指针(SP)所指向的存储单元是否已经保存有数据,可以分成两种情况,分别为“满堆栈”和“空堆栈”。这并不意味着堆栈是满的或者是空的,而是说当前SP指向的单元是否有有效数据的情况。 如果SP指向最后压入栈的有效数据项,称为满堆栈,这种堆栈的入栈操作要先将SP先调整然后再写入数据。 另外一种SP指向下一个待压入数据的空位置(SP指向的位置没有有效数据),称为空堆栈,这种堆栈的操作先写入数据再调整SP。


51单片机使用的是满堆栈的情况,SP总是默认指向07位置,相0的R7寄存器。插入数据时需要先将SP自增,然后才能写入数据。只是PUSH时,51自己完成了这个操作,但SP确实是指向了有效数据的位置。POP则相反,先赋值然后SP自减。


ARM支持这2种情况。结合起来ARM共支持4种堆栈类型,满递增,空递增,满递减,空递减。

阅读更多
换一批

没有更多推荐了,返回首页