51堆棧的安全(精確)設置
哈哈, 冷漠同學(xué)高深莫測,意識流的運用堪比大師. 好吧, 為了清晰起見(jiàn), 我替冷漠同學(xué)總結一下:
1) "假定項目中有3個(gè)匯編程序模塊A.a51,B.a51,C.a51,它們當然每個(gè)模塊都有自己的私有堆棧"
"BL51 A.OBJ,B.OBJ,C.OBJ
C51下的公有堆棧指針是?STACK ,而每個(gè)模塊的私有堆棧指針是STACK,一個(gè)公有?STACK里包含一個(gè)或者多個(gè)私有STACK,?STACK指針由編譯器確定分配在 idata 內所有段的最后面"
2) "只有PUSH / POP指令才能操作STACK,硬件自動(dòng)壓入的屬于不可控的系統控制棧,STACK根本不指向!2字節壓入PC根本不影響STACK指針"
3) "C程序中硬件自動(dòng)壓入的PC在私有STACK指向下面就完成了,用戶(hù)程序根本看不見(jiàn)的。好像稱(chēng)為系統控制棧內容"
4) " 私有堆棧(每個(gè)后臺函數的私有STACK,和C編譯器中的?STACK是兩回事)被編譯器分配在RAM低端,從全局靜態(tài)變量區(包括共享覆蓋區)后面開(kāi)始,即初始SP所指向區域,直到?STACK所指向為結束。
?STACK所指向的是前臺堆棧,被編譯器默認自動(dòng)分配在所有段(包括所有私有STACK段)的最后面(RAM高端)——棧頂部分!關(guān)鍵的是從這里開(kāi)始,直到棧頂,才存在溢出危險。——它是一個(gè)獨立ISR函數(不是多個(gè)后臺函數)的堆棧"
5)"對于interrupt 屬性函數,C51為其分配中斷函數私有堆棧……還有硬件堆棧hardware
引用結束.
假設:
有A.obj, B.obj, C.obj 三個(gè)模塊構成的一個(gè)8051單片系統, 使用了一個(gè)定時(shí)中斷, 簡(jiǎn)單起見(jiàn), 沒(méi)有使用 reentrant。其中a調用了b中的函數, b調用了c, c調用了a, 期間有中斷,而且沒(méi)有重新設置過(guò)sp。
請問(wèn)冷漠同學(xué):
1) 按照冷漠同學(xué)的解釋?zhuān)?此系統有: 中斷函數私有堆棧, abc模塊私有堆棧, 還有硬件堆棧hardware
2) 如果不是 5個(gè)棧, 這個(gè)系統總共有多少個(gè)棧? 請給出明確的數字。
3)每個(gè)棧是如何操作的? 請給出說(shuō)明。
冷漠修正一些錯誤:
1) "假定項目中有3個(gè)匯編程序模塊A.a51,B.a51,C.a51,它們當然每個(gè)模塊都有自己的私有堆棧"
"BL51 A.OBJ,B.OBJ,C.OBJ
C51下的公有堆棧指針是?STACK ,而每個(gè)模塊的私有堆棧指針是STACK,一個(gè)公有?STACK里包含一個(gè)或者多個(gè)私有STACK,?STACK指針由編譯器確定分配在 idata 內所有段的最后面"
——呵呵,這種概念所長(cháng)還不如老許理解透徹:一會(huì )給你抄抄操作系統的書(shū)。highgear是精通555時(shí)基的,怎 么可能理解這么深刻的機制?所長(cháng)從裸奔和匯編的概念出發(fā)當然不可能理解。不妨跟老許學(xué)學(xué):什么叫軟堆棧?如若誰(shuí)再提出個(gè)“軟中斷”,所長(cháng)該不會(huì )大呼小叫 吧。要不要冷漠給你注明哪本書(shū)上寫(xiě)的?你不可能比書(shū)作者還高明。
2) "只有PUSH / POP指令才能操作STACK,硬件自動(dòng)壓入的屬于不可控的系統控制棧,STACK根本不指向!2字節壓入PC根本不影響STACK指針"
3) "C程序中硬件自動(dòng)壓入的PC在私有STACK指向下面就完成了,用戶(hù)程序根本看不見(jiàn)的。好像稱(chēng)為系統控制棧內容"
——呵呵,硬件自動(dòng)壓入堆棧的PC影響的是?STACK,(幸虧冷漠前面沒(méi)有寫(xiě)問(wèn)號,也即SP指針。這稱(chēng)為“Hardware
4) " 私有堆棧(每個(gè)后臺函數的私有STACK,和C編譯器中的?STACK是兩回事)被編譯器分配在RAM低端,從全局靜態(tài)變量區(包括共享覆蓋區)后面開(kāi)始,即初始SP所指向區域,直到?STACK所指向為結束。
——冷漠的錯誤,先說(shuō)對不起了:“即初始SP所指向區 域,”這句話(huà)應該是……“從共享覆蓋區后面開(kāi)始,直到?STACK所指向為結束。”這正是老許說(shuō)的后臺軟堆棧區,它是人們匯編語(yǔ)言概念上的堆棧么?別以為 一個(gè)STACK命令分配區就認為是堆棧了??磿?shū)一點(diǎn)聯(lián)想里都沒(méi)有。難怪學(xué)不會(huì )操作系統。要不要我貼張圖講得更清楚一點(diǎn),文章出處當然就是P640啦,再回 家好好看看這一段。你不可能比書(shū)作者還高明。
待續……
TACK所指向的是前臺堆棧,被編譯器默認自動(dòng)分配在所有段(包括所有私有STACK段)的最后面(RAM高端)——棧頂部分!關(guān)鍵的是從這里開(kāi)始,直到棧頂,才存在溢出危險。——它是一個(gè)獨立ISR函數(不是多個(gè)后臺函數)的堆棧"
5)"對于interrupt 屬性函數,C51為其分配中斷函數私有堆棧……還有硬件堆棧hardware
引用結束.
哈哈, 冷漠同學(xué)概念混亂, 從頭到尾含糊其辭。冷漠同學(xué)既不敢明確回答有多少個(gè)棧, 也不敢***具體詳細*** 的解釋stack的原作過(guò)程。
我先把這里 stack 的具體化一些,
*) stack 操作是指影響 8051 sp 的操作, 如函數調用, push/pop.
*) sp 的活動(dòng)區域為 stack 區。
這樣, 計算機軟件算法的 stack 就不在此例。(呵呵, 在我面前賣(mài)弄 軟件stack和軟中斷, 如同賣(mài)弄bios 一樣可笑)。
我下面會(huì )把 ?stack 和 stack, 什么“私有模塊棧“ 講解清楚。 我不會(huì )比書(shū)作者還高, 但 keil 會(huì )。
書(shū)作者的問(wèn)題是沒(méi)有講清楚, 而冷漠的問(wèn)題是不清楚卻胡說(shuō)八道。
我先給出keil 關(guān)于 bl51 stack 的說(shuō)明, 對照 p640, 認真的看看, 就會(huì )知道原委.
http://www.keil.com/support/man/docs/bl51/bl51_stack.htm
■Use of the STACK directive to locate the ?STACK segment is typically not required.
■The STACK directive is typically used with assembly programs that have several stack segments.
■Use extreme caution when using the STACK directive. Improper use may result in a target program that crashes or that corrupts DATA and IDATA variables.
keil 從頭到尾沒(méi)有提出 "私有堆棧" (private stack) 的概念, 冷漠同學(xué)硬生生造出了很多的“術(shù)語(yǔ)“。
在講解 "私有堆棧" 來(lái)龍去脈前, 還是請冷漠明確的說(shuō)明有多少個(gè)涉及硬件棧指針的stack ? 2個(gè), 3個(gè)還是 5個(gè)?
“模塊私有棧“:
這個(gè)術(shù)語(yǔ)在徐愛(ài)鈞編著(zhù)P640里以及 keil 的網(wǎng)站里都沒(méi)有, 顯然是冷漠杜撰的, 如同"遞歸可重入“
Bl51 stack 命令參數看似可以設定一個(gè)”模塊私有棧”, 其實(shí)這個(gè)stack 命令參數的作用是為了匯編模塊,而且是需要重新設置 sp 的匯編模塊。 C 程序不需要關(guān)心 sp, 更不鼓勵用戶(hù)設置 sp. 只有匯編不得不這么做。匯編不得不自己設置 sp,不得不自己控制push/pop.
假設某個(gè)第三方的匯編模塊里改寫(xiě) sp (由于特殊的應用),此人為了通用,沒(méi)有直接設置 sp 為一個(gè)固定值,而是提供了一個(gè)sp地址的命名名稱(chēng), 如?ID?MEASURE,以便可以讓最終用戶(hù)在連接時(shí)由 linker 為?ID?MEASURE確定地址 。模塊結構大致如下:
Linker 在連接時(shí),可以自動(dòng)也可以手工用 stack參數設定?ID?MEASURE的具體位置, 并可以保留若干字節(8086 匯編里經(jīng)常有這種需求,為了不污染原來(lái)的stack). 這種 sp 被更改所產(chǎn)生的數據區域, 徐愛(ài)鈞的書(shū)以及 keil 稱(chēng)為棧段(stack segment), 沒(méi)有稱(chēng)為 "模塊私有棧".
因此, 只要模塊中沒(méi)有設置 sp, 那么就不會(huì )有stack segment, 也就是冷漠所說(shuō)的“模塊私有棧".
而 ?stack 僅僅是一個(gè)命名名稱(chēng),作用是在startup 初始化sp,即:
?stack 的值在連接時(shí)確定, 此外,別無(wú)特殊意義。當在某個(gè)模塊里重設sp 后,其后所有的?;顒?dòng)(call, interrupt, push, pop,ret,reti)都會(huì )從新棧點(diǎn)開(kāi)始。
.
.
.
結論:
a) 如果程序中, 用戶(hù)沒(méi)有重新設置 sp, 而且排除另一個(gè)概念---計算機軟件算法中的棧, 那么
b) 如果程序員在程序中多次設置 sp, 這些sp的活動(dòng)數據區被稱(chēng)為 stack segment, 而不是一個(gè)獨立的“stack"
如果對上述內容不能理解,請仔細閱讀鏈接中的內容
http://www.keil.com/support/man/docs/bl51/bl51_stack.htm
評論