51的棧是向高位址增長,intel
的8031、8032、8048、8051系列使用向高位址增長的堆疊;但同樣是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種堆疊型別,滿遞增,空遞增,滿遞減,空遞減。
棧的生長方向以及棧中的陣列
棧的生長方向分為向上生長和向下生長。看下圖 假定有兩個變數a和b,a先入棧,b 棧。如果a的記憶體位址大於b的記憶體位址,那麼棧的開口向下,反之棧的開口向上。看下面的 int a 10 int b 10 cout a b endl 我這裡是看口向下 debug 但release下棧看口向上生長 那麼...
棧的增長方向
如何判斷棧的增長方向?對於乙個用慣了i386系列機器的人來說,這似乎是乙個無聊的問題,因為棧就是從高位址向低位址增長。不過,顯然這不是這個問題的目的,既然把這個問題拿出來,問的就不只是i386系列的機器,跨硬體平台是這個問題的首先要考慮到的因素。在乙個物質極大豐富的年代,除非無路可退,否則我們堅決不...
大小端模式,棧的生長方向和記憶體的存放方向
棧的生長方向和記憶體的存放方向 棧的開口向下,高位址在上,低位址在下 記憶體的存放方向 自下向上 define crt secure no warnings include include include 1.棧的生長方向 void test01 2.記憶體生長方向 小端模式 void test02...