<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51堆棧的安全(精確)設(shè)置

          51堆棧的安全(精確)設(shè)置

          作者: 時間:2016-11-28 來源:網(wǎng)絡(luò) 收藏

          關(guān)鍵還是主題。

          哈哈, 冷漠同學(xué)高深莫測,意識流的運(yùn)用堪比大師. 好吧, 為了清晰起見, 我替冷漠同學(xué)總結(jié)一下:

          1) "假定項目中有3個匯編程序模塊A.a51,B.a51,C.a51,它們當(dāng)然每個模塊都有自己的私有堆棧"
          "BL51 A.OBJ,B.OBJ,C.OBJSTACK(?DT?A(50H),B(60H),C(70H))
          C51下的公有堆棧指針是?STACK ,而每個模塊的私有堆棧指針是STACK,一個公有?STACK里包含一個或者多個私有STACK,?STACK指針由編譯器確定分配在 idata 內(nèi)所有段的最后面"

          2) "只有PUSH / POP指令才能操作STACK,硬件自動壓入的屬于不可控的系統(tǒng)控制棧,STACK根本不指向!2字節(jié)壓入PC根本不影響STACK指針"

          3) "C程序中硬件自動壓入的PC在私有STACK指向下面就完成了,用戶程序根本看不見的。好像稱為系統(tǒng)控制棧內(nèi)容"

          4) " 私有堆棧(每個后臺函數(shù)的私有STACK,和C編譯器中的?STACK是兩回事)被編譯器分配在RAM低端,從全局靜態(tài)變量區(qū)(包括共享覆蓋區(qū))后面開始,即初始SP所指向區(qū)域,直到?STACK所指向為結(jié)束。

          ?STACK所指向的是前臺堆棧,被編譯器默認(rèn)自動分配在所有段(包括所有私有STACK段)的最后面(RAM高端)——棧頂部分!關(guān)鍵的是從這里開始,直到棧頂,才存在溢出危險。——它是一個獨(dú)立ISR函數(shù)(不是多個后臺函數(shù))的堆棧"

          5)"對于interrupt 屬性函數(shù),C51為其分配中斷函數(shù)私有堆棧……還有硬件堆棧hardwarestack 的概念"

          引用結(jié)束.
          假設(shè):
          有A.obj, B.obj, C.obj 三個模塊構(gòu)成的一個8051單片系統(tǒng), 使用了一個定時中斷, 簡單起見, 沒有使用 reentrant。其中a調(diào)用了b中的函數(shù), b調(diào)用了c, c調(diào)用了a, 期間有中斷,而且沒有重新設(shè)置過sp。

          請問冷漠同學(xué):

          1) 按照冷漠同學(xué)的解釋, 此系統(tǒng)有: 中斷函數(shù)私有堆棧, abc模塊私有堆棧, 還有硬件堆棧hardwarestack. 一共 1+3+1 = 5 個棧
          2) 如果不是 5個棧, 這個系統(tǒng)總共有多少個棧? 請給出明確的數(shù)字。
          3)每個棧是如何操作的? 請給出說明。


          冷漠修正一些錯誤:

          1) "假定項目中有3個匯編程序模塊A.a51,B.a51,C.a51,它們當(dāng)然每個模塊都有自己的私有堆棧"
          "BL51 A.OBJ,B.OBJ,C.OBJSTACK(?DT?A(50H),B(60H),C(70H))
          C51下的公有堆棧指針是?STACK ,而每個模塊的私有堆棧指針是STACK,一個公有?STACK里包含一個或者多個私有STACK,?STACK指針由編譯器確定分配在 idata 內(nèi)所有段的最后面"
          ——呵呵,這種概念所長還不如老許理解透徹:一會給你抄抄操作系統(tǒng)的書。highgear是精通555時基的,怎 么可能理解這么深刻的機(jī)制?所長從裸奔和匯編的概念出發(fā)當(dāng)然不可能理解。不妨跟老許學(xué)學(xué):什么叫軟堆棧?如若誰再提出個“軟中斷”,所長該不會大呼小叫 吧。要不要冷漠給你注明哪本書上寫的?你不可能比書作者還高明。
          2) "只有PUSH / POP指令才能操作STACK,硬件自動壓入的屬于不可控的系統(tǒng)控制棧,STACK根本不指向!2字節(jié)壓入PC根本不影響STACK指針"
          3) "C程序中硬件自動壓入的PC在私有STACK指向下面就完成了,用戶程序根本看不見的。好像稱為系統(tǒng)控制棧內(nèi)容"

          ——呵呵,硬件自動壓入堆棧的PC影響的是?STACK,(幸虧冷漠前面沒有寫問號,也即SP指針。這稱為“Hardwarestack”,別混為一談,裝明白人了。要不要冷漠注明摘自那本書?——你不可能比書作者高明 ??!


          4) " 私有堆棧(每個后臺函數(shù)的私有STACK,和C編譯器中的?STACK是兩回事)被編譯器分配在RAM低端,從全局靜態(tài)變量區(qū)(包括共享覆蓋區(qū))后面開始,即初始SP所指向區(qū)域,直到?STACK所指向為結(jié)束。

          ——冷漠的錯誤,先說對不起了:“即初始SP所指向區(qū) 域,”這句話應(yīng)該是……“從共享覆蓋區(qū)后面開始,直到?STACK所指向為結(jié)束。”這正是老許說的后臺軟堆棧區(qū),它是人們匯編語言概念上的堆棧么?別以為 一個STACK命令分配區(qū)就認(rèn)為是堆棧了??磿稽c(diǎn)聯(lián)想里都沒有。難怪學(xué)不會操作系統(tǒng)。要不要我貼張圖講得更清楚一點(diǎn),文章出處當(dāng)然就是P640啦,再回 家好好看看這一段。你不可能比書作者還高明。

          待續(xù)……
          TACK所指向的是前臺堆棧,被編譯器默認(rèn)自動分配在所有段(包括所有私有STACK段)的最后面(RAM高端)——棧頂部分!關(guān)鍵的是從這里開始,直到棧頂,才存在溢出危險。——它是一個獨(dú)立ISR函數(shù)(不是多個后臺函數(shù))的堆棧"

          5)"對于interrupt 屬性函數(shù),C51為其分配中斷函數(shù)私有堆棧……還有硬件堆棧hardwarestack 的概念"

          引用結(jié)束.

          哈哈, 冷漠同學(xué)概念混亂, 從頭到尾含糊其辭。冷漠同學(xué)既不敢明確回答有多少個棧, 也不敢***具體詳細(xì)*** 的解釋stack的原作過程。

          我先把這里 stack 的具體化一些,以免誤解引申:
          *) stack 操作是指影響 8051 sp 的操作, 如函數(shù)調(diào)用, push/pop.
          *) sp 的活動區(qū)域為 stack 區(qū)。
          這樣, 計算機(jī)軟件算法的 stack 就不在此例。(呵呵, 在我面前賣弄 軟件stack和軟中斷, 如同賣弄bios 一樣可笑)。

          我下面會把 ?stack 和 stack, 什么“私有模塊棧“ 講解清楚。 我不會比書作者還高, 但 keil 會。
          書作者的問題是沒有講清楚, 而冷漠的問題是不清楚卻胡說八道。

          我先給出keil 關(guān)于 bl51 stack 的說明, 對照 p640, 認(rèn)真的看看, 就會知道原委.

          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 從頭到尾沒有提出 "私有堆棧" (private stack) 的概念, 冷漠同學(xué)硬生生造出了很多的“術(shù)語“。

          在講解 "私有堆棧" 來龍去脈前, 還是請冷漠明確的說明有多少個涉及硬件棧指針的stack ? 2個, 3個還是 5個?

          “模塊私有棧“:
          這個術(shù)語在徐愛鈞編著P640里以及 keil 的網(wǎng)站里都沒有, 顯然是冷漠杜撰的, 如同"遞歸可重入“

          Bl51 stack 命令參數(shù)看似可以設(shè)定一個”模塊私有棧”, 其實這個stack 命令參數(shù)的作用是為了匯編模塊,而且是需要重新設(shè)置 sp 的匯編模塊。 C 程序不需要關(guān)心 sp, 更不鼓勵用戶設(shè)置 sp. 只有匯編不得不這么做。匯編不得不自己設(shè)置 sp,不得不自己控制push/pop.

          假設(shè)某個第三方的匯編模塊里改寫 sp (由于特殊的應(yīng)用),此人為了通用,沒有直接設(shè)置 sp 為一個固定值,而是提供了一個sp地址的命名名稱, 如?ID?MEASURE,以便可以讓最終用戶在連接時由 linker 為?ID?MEASURE確定地址 。模塊結(jié)構(gòu)大致如下:
          ?ID?MEASURE segment idata
          rseg?ID?MEASURE
          ds1

          mov SP, #?ID?MEASURE

          Linker 在連接時,可以自動也可以手工用 stack參數(shù)設(shè)定?ID?MEASURE的具體位置, 并可以保留若干字節(jié)(8086 匯編里經(jīng)常有這種需求,為了不污染原來的stack). 這種 sp 被更改所產(chǎn)生的數(shù)據(jù)區(qū)域, 徐愛鈞的書以及 keil 稱為棧段(stack segment), 沒有稱為 "模塊私有棧".

          因此, 只要模塊中沒有設(shè)置 sp, 那么就不會有stack segment, 也就是冷漠所說的“模塊私有棧".

          而 ?stack 僅僅是一個命名名稱,作用是在startup 初始化sp,即:
          mov sp, #?stack - 1
          ?stack 的值在連接時確定, 此外,別無特殊意義。當(dāng)在某個模塊里重設(shè)sp 后,其后所有的?;顒?call, interrupt, push, pop,ret,reti)都會從新棧點(diǎn)開始。
          .
          .
          .

          結(jié)論:
          a) 如果程序中, 用戶沒有重新設(shè)置 sp, 而且排除另一個概念---計算機(jī)軟件算法中的棧, 那么
          *) 不存在所謂的“模塊私有棧“, 不論有多少模塊
          *)只有一個涉及sp 的棧,沒有其他的亂七八糟的棧

          b) 如果程序員在程序中多次設(shè)置 sp, 這些sp的活動數(shù)據(jù)區(qū)被稱為 stack segment, 而不是一個獨(dú)立的“stack"

          如果對上述內(nèi)容不能理解,請仔細(xì)閱讀鏈接中的內(nèi)容
          http://www.keil.com/support/man/docs/bl51/bl51_stack.htm

          上一頁 1 2 下一頁

          關(guān)鍵詞: 51堆棧安全設(shè)

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();