標(biāo)題: 關(guān)于堆棧和ram的問題 [打印本頁]

作者: zjm001    時間: 2024-10-31 11:14
標(biāo)題: 關(guān)于堆棧和ram的問題
rt,51單片機(jī)中的用戶ram是從30h-7fh,堆棧也是在這個區(qū)域中,有幾個問題;1.請問如果用push/pop的堆棧區(qū)域的總?cè)萘渴嵌嗌?是直接?0h開始連續(xù)存放嗎?如果是這樣的話那么通過直接尋址就能訪問到堆棧中元素了,是不是和堆棧思想不符?
2. 堆棧的容量是固定的嗎,會小于整體用戶ram區(qū)容量嗎?如果是的話如果自己用ram中非堆棧區(qū)作為自己的臨時變量應(yīng)該從多少地址開始?

謝謝


作者: xiaobendan001    時間: 2024-10-31 17:57
用C,不用關(guān)心這些吧
作者: 188610329    時間: 2024-10-31 18:36
51單片機(jī)的堆棧 存放起始位置 由 寄存器 SP 設(shè)定。
通常,如果C語言編譯,并且加載了 STARTUP.A51 引導(dǎo)程序,SP默認(rèn)為 用于變量聲明結(jié)束后位置。
至于堆棧容量多大,站在51單片機(jī)的硬件角度看,理論上可以最大256字節(jié),當(dāng)然,這是理論上。實際應(yīng)用時寄存器組最少需要8個字節(jié),那么,即使你的代碼中沒有聲明任何變量,堆棧也只有248字節(jié)了,加上如果用的 AT89C51 RAM只有128 那么,實際堆?墒褂米畲笕萘恐挥120字節(jié)。
又因為堆棧只能順序往后遞增,一旦你有聲明 位 變量,必須占用 20H 字節(jié)地址,那么 堆棧最少要從 21H 位置開始,這樣可以使用的堆棧容量最大只有95字節(jié)。
作者: zjm001    時間: 2024-10-31 19:51
188610329 發(fā)表于 2024-10-31 18:36
51單片機(jī)的堆棧 存放起始位置 由 寄存器 SP 設(shè)定。
通常,如果C語言編譯,并且加載了 STARTUP.A51 引導(dǎo)程 ...

請問如果是匯編呢?
作者: suncat0504    時間: 2024-10-31 21:23
匯編也好,C也好,都涉及SP的設(shè)置。只不過C中幫你做了處理。在匯編中,你需要根據(jù)程序中中斷的多少,子程序的嵌套調(diào)用級數(shù),確定堆棧的深度。中斷處理越多,子程序嵌套越多,就越需要堆棧的深度。
作者: Y_G_G    時間: 2024-11-1 00:19
1,堆棧區(qū)域的總?cè)萘渴嵌嗌伲?br /> 這并不重要,重要的是你要了解單片機(jī)編程的原理,對于8051而言,30h-7fh都可以
但一個合格的單片機(jī)C語言程序,16層的堆棧幾乎能應(yīng)對99.9%的程序,再不行可以用32層
也就是
MOV SP, #5FH
如果你還不明白我說的是什么,那就得再去看一上單片機(jī)編程的原理,因為,并不是所有的單片機(jī)都是像51這樣,用軟件堆棧的,有的是硬件堆棧,而且只有4層,如果你不了解其中的原理,到時候?qū)懫鸫a來,問題很多的
2,這個問題參考上面的回答就可以了
作者: ydatou    時間: 2024-11-1 09:23
1. 51的堆棧通常安排在ram區(qū)的最后區(qū)域,一般情形下有30個字節(jié)夠用了,即60h-7fh(或e0h-ffh),堆棧容量當(dāng)然越大越好。
2. c編譯器會自動安排,把未用到的ram全部用作堆棧。你只要確認(rèn)編譯后用到的的data區(qū)小于96(或220)字節(jié),否則要修改代碼。
匯編非常靈活,堆?砂才旁20H后的任意區(qū)域。假如按C編譯器的做法(推薦),自己的臨時變量是從地址20h開始。
作者: zjm001    時間: 2024-11-1 20:57
Y_G_G 發(fā)表于 2024-11-1 00:19
1,堆棧區(qū)域的總?cè)萘渴嵌嗌伲?br /> 這并不重要,重要的是你要了解單片機(jī)編程的原理,對于8051而言,30h-7fh都可以
...

我之前是使用8086匯編的,在調(diào)用子程序的時候需要進(jìn)行保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場,會用到很多的堆棧來干這個事,請問51中也是需要這樣做嗎?我看很多的視頻和教材里都是只保存PC和PSW
作者: Y_G_G    時間: 2024-11-1 22:46
首先,你要知道單片機(jī)選擇匯編的原因
1,之前版本的穩(wěn)定量產(chǎn)程序是匯編的,新產(chǎn)品只要稍稍改一小部分就可以生產(chǎn)的
2,片上資源實在太少了,比如,RAM只48B這種的低端單片機(jī)
3,單片機(jī)本身就沒有C編譯器,只能用匯編
4,對時序要求非常嚴(yán)格的,精確到一個時鐘的程序
除了以上說的,沒有其它理由再選擇匯編了,相信我,我用了3年的匯編,現(xiàn)在用C了
作者: Y_G_G    時間: 2024-11-1 22:58
教材里都是只保存PC和PSW,那是因為沒有用到其它的地址,其它地址的數(shù)據(jù)沒有什么改變,不需要做什么事情
如果累加器A在別的子程序中用到,而中斷中也用到A的話,這個時候就要保存A了,同理,R2-R7也一樣的
只要中斷服務(wù)中斷外的子程序都用到一個地址的時候,中斷就要進(jìn)行現(xiàn)場保護(hù)
對于你而言,我建議是放棄匯編,去用C,如果不會C,也可能現(xiàn)在開始學(xué)C,可能剛開始的時候有點不習(xí)慣,但是,不管是現(xiàn)在還是將來,C一定是單片機(jī)最好的選擇,熟練C要比熟練匯編好上很多倍
上古時期的東西,不需要學(xué),不要迷戀網(wǎng)上說的那些匯編的好處,也不要覺得匯編是基礎(chǔ),必需要學(xué)的
沒有必要,你看現(xiàn)在,誰還學(xué)機(jī)器語言,操作碼的

作者: 188610329    時間: 2024-11-2 00:42
zjm001 發(fā)表于 2024-11-1 20:57
我之前是使用8086匯編的,在調(diào)用子程序的時候需要進(jìn)行保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場,會用到很多的堆棧來干這個事, ...

51而言,PC是硬件層直接 入棧的,會占用堆棧的兩個字節(jié),但是,不需要你手動去操作,當(dāng)你 CALL 的時候,就入棧,RET的時候 就自動出棧,同理當(dāng)中斷觸發(fā)時,PC會自動入棧,當(dāng)執(zhí)行到 RETI時就會自動出棧。而其他的寄存器,比如,PSW, ACC, DPTR 這些,就要你自己手動的一個個 PUSH 和 POP了。至于保存哪些,取決于你的子程序 需要用到哪些,比如,你的子程序中 需要 執(zhí)行,MOVC   A,@A+DPTR  那么,你肯定需要把 ACC, DPL, DPH 都入棧了,
作者: 人中狼    時間: 2024-11-2 08:48
你可以看看51的教材,你說使用過8086的匯編,那么你所提的問題也就是說你沒有看過51的教材,關(guān)于51的堆棧,教材中是一定會有說明的
作者: 萬家燈火51    時間: 2024-11-2 12:43
棧是為臨時變量開辟的區(qū)域,大小應(yīng)該不能固定。因為涉及函數(shù)調(diào)用,嵌套層數(shù)多,空間就用得多。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1