为什么栈和堆的生长方向不一样
棧的生長方向
8051的棧是向高地址增長,INTEL的8031、8032、8048、8051系列使用向高地址增長的堆棧;但同樣是INTEL,在x86系列中全部使用向低地址增長的堆棧。其他公司的CPU中除ARM的結構提供向高地址增長的堆棧選項外,多數都是使用向低地址增長的堆棧。
?
歷史原因
在沒有MMU的時代,為了最大的利用內存空間,堆和棧被設計為從兩端相向生長。那么哪一個向上,哪一個向下呢?
? 人們對數據訪問是習慣于向上的,比如你在堆中new一個數組,是習慣于把低元素放到低地址,把高位放到高地址,所以堆向上生長比較符合習慣。而棧則對方向不敏感,一般對棧的操作只有PUSH和pop,無所謂向上向下,所以就把堆放在了低端,把棧放在了高端。MMU出來后就無所謂了,只不過也沒必要改了。
? 51這種單片機,沒有堆,只有棧,所以把棧設計成向上,有利于擴展,比如52在127后面加個128個字節,程序就不必修改可以直接移植,如果是向下的話要利用這多出來的128字節就要修改程序,改變堆棧指針了。
?
數據間的地址高低看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種堆棧類型,滿遞增,空遞增,滿遞減,空遞減。
?
說明:此文整理自網絡,原文地址:http://www.dzsc.com/dzbbs/20061126/200765184739359366.html
總結
以上是生活随笔為你收集整理的为什么栈和堆的生长方向不一样的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux环境程序栈溢出原理
- 下一篇: Linux查看多核CPU利用率