在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在MAXQ2000數據存儲器中實現軟堆棧

星星科技指導員 ? 來源:ADI ? 作者:ADI ? 2023-02-14 18:20 ? 次閱讀

MAXQ2000微控制器MaximRISC微控制器系列MAXQ器件一樣,都是基于MAXQ20內核。基于MAXQ20的微控制器通常可實現一個16位寬硬堆棧,其深度固定不變(MAXQ2000為16),存儲在與數據和程序空間分開的專用內部存儲器中。通過子程序調用和中斷,這一硬堆棧可用于保存和恢復微控制器的操作狀態。

雖然非常適合緊湊型應用,但是在規模較大的匯編應用中,使用深度嵌套的子程序(或者使用了在堆棧中保存和恢復多個工作寄存器的子程序),硬堆棧會很快耗盡空間。利用數據存儲器中的“軟堆棧”,以C編程語言(使用IAR的Embedded Workbench?等編譯器)或者Rowley Associates的Crossworks for MAXQ編寫應用程序可避免這一問題。這一軟堆棧存儲子程序的調用/返回地址以及本地工作變量。然而,MAXQ20內核沒有內置機制來定位數據存儲器中的堆棧,這些數據存儲器只用在匯編應用中。

本應用筆記介紹了匯編應用中在數據存儲器中實現軟堆棧的簡單方法。應用筆記中的代碼可以用于MAXQ2000和其他基于MAXQ20的微控制器。采用了MAX-IDE的宏預處理特性,在Maxim的MAXQ系列工程應用開發和調試環境中編寫了實例代碼。

可以免費下載MAX-IDE環境最新的安裝包和文檔:

MAX-IDE安裝(ZIP)

MAXQ內核匯編指南(PDF)

開發工具指南(PDF)

MAXQ20內核中的硬堆棧工作

MAXQ20內核使用了兩種不同類型的堆棧工作模式:

PUSH工作(它包括操作代碼PUSH、LCALL和SCALL)被用于在堆棧中存儲數據。這些操作將堆棧指針SP預增1,然后,把數據存儲在SP指針(@SP)指向的堆棧位置。

POP工作(它包括操作代碼POP、POPI、RET和RETI)被用于從堆棧中恢復數據。這些操作從SP指向的堆棧位置恢復數據,然后,將堆棧指針減1。

硬堆棧的一項主要功能是在調用子程序時保存并恢復地址,因此,堆棧含有16位(字)位置。這一位寬支持在一次push或者pop操作中保存或者恢復16位指令指針(IP)寄存器。盡管可以使用PUSH或者POP在堆棧中保存或者恢復8位寄存器(例如,AP),但每一堆棧操作總是使用整個16位字。

除了利用堆棧的各種操作代碼之外,還有兩種其他的情況,在這些情況下,微控制器自動使用硬堆棧:

當處理中斷時,開始執行中斷服務程序(中斷矢量寄存器IV所指)之前,當前程序執行點被推入堆棧。

當調用某些調試命令(例如,讀寄存器和寫數據存儲器)時,需要執行完程序ROM中的代碼,在控制被傳送給程序ROM之前,當前的執行點被推入堆棧。一旦執行完程序ROM中的調試程序,執行點從堆棧中彈出,恢復處理器以前的狀態。

找到中斷服務程序或者執行調試器命令總是需要使用硬堆棧。由于這一行為嵌入在硬件中,因此,無法避開這一問題。然而,對于更常用的PUSH/POP和CALL/RET指令對,可以采用軟堆棧。

注意,當以下任一堆棧錯誤狀態出現時,MAXQ2000 (和其他的基于MAXQ20內核的器件一樣)并不支持任何錯誤探測或者報警:

堆棧上溢:將數值推入已經滿的堆棧時發生。這一錯誤導致堆棧中最早的數值被覆寫。

堆棧下溢:從空堆棧中彈出數值時發生。這一錯誤導致返回無效數據值。例如,如果堆棧空時執行RET,執行后將返回一個不正確的(有可能是隨機的)地址。

在數據存儲器中建立一個軟堆棧

在數據存儲器中建立一個軟堆棧的第一步是定義要使用數據存儲器的哪一部分。然后,必須定義跟蹤堆棧頂當前位置的數據存儲器指針(DP[0]、DP[1]或者BP[Offs])。注意:應用軟件不會出于其他目的使用堆棧專用數據存儲器(例如,變量或者緩沖)。

定義并初始化這類軟堆棧的一種簡單方法涉及到BP[Offs]寄存器對和一個公式。

SS_BASE  equ  0100h

ss_init:
   move    DPC,  #1Ch        ; Set all pointers to word mode   
   move    BP,   #SS_BASE    ; Set base pointer to stack base location
   move    Offs, #0          ; Set stack to start
   ret

如果基指針(BP)寄存器被設置在SS_BASE位置,那么,可以采用Offs寄存器指向堆棧的當前頂部。由于Offs寄存器只有8位寬,硬件會自動把堆棧限制在數據存儲器的范圍內(BP .. (BP+255))。如果當Offs等于255 (上溢)時出現推入,或者Offs等于0 (下溢)時出現彈出,那么,Offs寄存器只會限制在堆棧的另一端。這一行為模仿硬堆棧工作方式,支持簡單的軟堆棧實現;它不探測下溢和上溢狀態。

在使用軟堆棧前,主程序必須調用ss_init例程。它將BP[Offs]指針設置為字模式,由于軟堆棧以16位寬堆棧實現,因此,必須完成這一步。它還將BP[Offs]寄存器對指向堆棧開始。

軟堆棧工作

不能重新定義使用堆棧的內置操作代碼(PUSH、POP、CALL、RET等)以使用軟堆棧,這是因為這些代碼意味著MAXQ匯編器的硬線連接。而且,還有可能需要在應用程序中的某些部分使用標準硬堆棧,例如,中斷服務例程等。出于這些原因,由復制標準操作代碼的宏來訪問軟堆棧。

mpush  MACRO  Reg
   move    @BP[++Offs], Reg  ; Push value to soft stack
endm

mpop   MACRO  Reg
   move    Reg, @BP[Offs--]  ; Pop value from soft stack
endm

mcall  MACRO  Addr
LOCAL  return
   move    @BP[++Offs], #return   ; Push return destination to soft stack
   jump    Addr
return:
endm

mret   MACRO
   jump    @BP[Offs--]       ; Jump to popped destination from soft stack
endm

下面將討論這些宏是怎樣工作的。

mpush

該宏的使用方式和PUSH操作代碼相同。它支持將8位或者16位寄存器,或者將立即值推入堆棧。

 mpush   A[0]              ; Save the value of the A[0] register
   mpush   A[1]              ; Save A[1]
   mpush   A[2]              ; Save A[2]

   ...                       ; code which destroys A[0]-A[2]

   mpop    A[2]              ; Restore the value of A[2] (pop in reverse order)
   mpop    A[1]              ; Restore A[1]
   mpop    A[0]              ; Restore A[0]

mpop

該宏的使用方式和POP操作代碼相同。它支持從堆棧中裝入8位或者16位寄存器,如上所示。注意,如果推入了一個16位值,該值彈入到一個8位寄存器中,那么,只有低位字節被存儲在寄存器中。高位字節丟失。這與內置硬堆棧的方式一致。

subroutine:
   mpush   A[0]              ; Save the current value of A[0]
   
   ...                       ; Code which destroys A[0]

   mpop    A[1]              ; Restore A[0]
   mret

mcall
mret

mcall宏的使用方式和CALL操作代碼執行子程序相同。一旦執行完成,子程序必須使用mret宏(而不是標準RET操作代碼)才能返回。

 mcall   mySub

   ...

mySub:
   mpush   A[0]              ; Save A[0]
   mpush   A[1]              ; Save A[1]
   ...                       ; Perform calculations, etc.
   mpop    A[1]
   mpop    A[0]
   mret

擴展軟堆棧的大小

某些應用程序需要大于256級的軟堆棧。使用其他數據指針(DP[0]或者DP[1])之一可以實現任意大小的堆棧(最大達到數據存儲器的上限)。

SS_BASE  equ  0000h
SS_TOP   equ  01FFh

ss_init:
   move    DPC,   #1Ch       ; Set all data pointers to word mode
   move    DP[0], #SS_BASE   ; Set pointer to stack base location
   ret

上面的代碼存儲在數據存儲器的0000h至01FFh,因此,產生的堆棧可以保持511級。(沒有使用堆棧存儲器空間中的某一位置;這樣可以更有效,以更短的代碼實現

只改變數據指針,而代碼中的其他部分保持不變可以擴展堆棧。雖然如此,由于DP[0]并沒有限制在數據存儲器的一定范圍內,因此,沒有措施來防止推入或者彈出操作使DP[0]增加或者減小導致超出所指定的軟堆棧邊界。為避免這一點,可以加入簡單的下溢/上溢檢查。

加入下溢和上溢檢查

為保持宏(每次使用時擴展為代碼)盡量短,在子程序中完成下溢和上溢檢查,使用硬堆棧,由宏調用子程序。

mpush  MACRO  Reg
   call    ss_check_over     ; Check for possible overflow
   move    @++DP[0], Reg     ; Push value to soft stack
endm

mpop   MACRO  Reg
   call    ss_check_under    ; Check for possible underflow
   move    Reg, @DP[0]--     ; Pop value from soft stack
endm

mcall  MACRO  Addr
LOCAL  return
   call    ss_check_over     ; Check for possible overflow
   move    @++DP[0], #return ; Push return destination to soft stack
   jump    Addr
return:
endm

mret   MACRO
   call    ss_check_under    ; Check for possible underflow
   jump    @DP[0]--          ; Jump to popped destination from soft stack
endm

ss_check_under:
   push    A[0]
   push    AP
   push    APC
   push    PSF   

   move    APC, #80h         ; Set Acc to A[0], standard mode, no auto inc/dec
   move    Acc, DP[0]        ; Get current value of stack pointer
   cmp     #SS_BASE
   jump    NE, ss_check_under_ok
   nop                       ; < Error handler should be implemented here >
ss_check_under_ok:
   pop     PSF
   pop     APC
   pop     AP
   pop     A[0]
   ret

ss_check_over:
   push    A[0]
   push    AP
   push    APC
   push    PSF   

   move    APC, #80h         ; Set Acc to A[0], standard mode, no auto inc/dec
   move    Acc, DP[0]        ; Get current value of stack pointer
   cmp     #SS_TOP
   jump    NE, ss_check_over_ok
   nop                       ; < Error handler should be implemented here >
ss_check_over_ok:
   pop     PSF
   pop     APC
   pop     AP
   pop     A[0]
   ret

上面的代碼導致在推入或者彈出(或者call,或者ret)操作之前檢查當前的堆棧位置。如果探測到下溢或者上溢錯誤,不同的應用程序有不同的響應。一般情況下,這類錯誤只會出現在應用程序開發階段;如果代碼編寫正確,不會出現這類錯誤。如果的確出現了錯誤,一般將其考慮為重大錯誤,就像使用硬堆棧時出現下溢/上溢錯誤。對這類錯誤可能的響應包括暫停,發送錯誤消息,或者閃爍LED。在開發階段,一個好的方法是兩個程序中的每一個都在MAX-IDE中設置斷點(例如,在“Error handler should be implemented here”行中),如果出現下溢或者上溢,立即發出反饋。

但是,應用程序有時候也可以從堆棧下溢或者上溢中恢復(例如,重新裝入和從頭重新啟動應用程序子任務)。在這種情況下,需要簡單地設置一個標志,指示出現了堆棧錯誤。可選的這類標志包括位于PSF寄存器中的兩個通用標志(GPF0和GPF1)。由于有兩個位標志,因此,其中一個可以用于指示上溢,另一個用于指示下溢。

結論

MAX-IDE強大的宏預處理功能實現了MAXQ2000以及其他MAXQ20微控制器數據存儲器軟堆棧的直接替換。這一軟堆棧使子程序更加模塊化,可重復使用,有助于大規模匯編應用程序的開發。堆棧還支持堆棧錯誤的探測。

審核編輯:郭婷

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7574

    瀏覽量

    151707
  • 存儲器
    +關注

    關注

    38

    文章

    7517

    瀏覽量

    164065
收藏 人收藏

    評論

    相關推薦

    MAXQ2000 SPI模塊與MAX6951/MAX6950怎么配合使用?

    本應用筆記提供了MAXQ?匯編程序范例,說明MAXQ2000 SPI模塊與MAX6951/MAX6950的配合使用。
    發表于 05-31 06:08

    MAXQ2000微控制與MAX4397是如何連接的?

    MAX4397是什么?MAXQ2000微控制與MAX4397是如何連接的?
    發表于 06-04 06:15

    MAXQ2000文資料pdf

    MAXQ2000微控制是低功耗16位器件,包含液晶顯示(LCD)接口,可以驅動最多100 (-RBX/-RBX+)段或132 (-RAX/-RAX+/-RFX/-RFX+)段。MAXQ2000適用于血糖監測系統,也適用于其他需
    發表于 06-30 11:29 ?97次下載

    利用MAXQ2000微控制實現快速傅里葉變換

    利用MAXQ2000微控制實現快速傅里葉變換
    發表于 12-13 17:24 ?19次下載
    利用<b class='flag-5'>MAXQ2000</b>微控制<b class='flag-5'>器</b><b class='flag-5'>實現</b>快速傅里葉變換

    采用MAXQ2000進行音頻濾波

    集成了乘累加單元(MAC)和單周期內核的MAXQ2000非常適合用作通用微控制MAXQ2000所具有的性能和I/O外設適合多種應用:如鬧鐘、手持醫療設備、數字讀取等需要低功耗、高
    發表于 12-25 23:24 ?34次下載

    用uIP堆棧實現MAXQ微控制聯網-MAXQ2000的應用

    用uIP堆棧實現MAXQ微控制聯網 摘要:本應用筆記描述了如何用uIP TCP/IP網絡協議棧實現M
    發表于 08-04 09:47 ?513次閱讀
    用uIP<b class='flag-5'>堆棧</b><b class='flag-5'>實現</b><b class='flag-5'>MAXQ</b>微控制<b class='flag-5'>器</b>聯網-<b class='flag-5'>MAXQ2000</b>的應用

    MAXQ2000數據存儲器實現堆棧

    摘要:本應用筆記介紹了匯編應用數據存儲器實現堆棧的簡單方法。該方法使用了
    發表于 04-23 16:04 ?972次閱讀

    利用MAXQ2000設計電壓表

    摘要:本應用筆記演示了如何配置MAXQ2000微控制實現簡單的電壓表設計。該應用采用MAXQ2000評估板,其中包括4½位段式LCD顯示
    發表于 04-23 16:07 ?837次閱讀
    利用<b class='flag-5'>MAXQ2000</b>設計電壓表

    利用SD存儲介質擴展MAXQ2000的非易失性數據存儲空間

    摘要:本文討論如何使用安全數字(SD)媒體格式擴展MAXQ2000的非易失數據存儲器。 低功耗、低噪聲的MAXQ2000微控制適合于多種應
    發表于 04-23 16:25 ?1207次閱讀
    利用SD<b class='flag-5'>存儲</b>介質擴展<b class='flag-5'>MAXQ2000</b>的非易失性<b class='flag-5'>數據</b><b class='flag-5'>存儲</b>空間

    采用MAXQ2000進行音頻濾波

    摘要:集成了乘累加單元(MAC)和單周期內核的MAXQ2000非常適合用作通用微控制(µC) 。MAXQ2000所具有的性能和I/O外設適合多種應用:如鬧鐘、手持醫療設備、數字讀取
    發表于 04-23 17:27 ?1087次閱讀
    采用<b class='flag-5'>MAXQ2000</b>進行音頻濾波

    采用MAXQ2000微控制和MAX6970 LED驅動

    采用MAXQ2000微控制和MAX6970 LED驅動顯示不同的LED排序 Abstract: This note shows an application circuit
    發表于 07-25 21:07 ?869次閱讀

    利用SD存儲介質擴展MAXQ2000數據存儲空間

    本文討論如何使用安全數字(SD)媒體格式打“展MAXQ2000的非易失數據存儲器
    發表于 04-08 09:59 ?4次下載

    MAXQ2000數據存儲器實現堆棧

    本應用筆記演示了一種在數據存儲器實現堆棧的簡單方法,用于基于匯編的應用。該方法使用
    的頭像 發表于 01-11 11:20 ?739次閱讀

    使用鍵盤和LCD顯示屏與MAXQ2000

    MAXQ2000通過專用的LCD控制外設輕松直接地與LCD顯示接口。使用MAXQ2000提供的靈活端口引腳配置,可以直接讀取多路復用鍵盤。中斷驅動的狀態機允許
    的頭像 發表于 02-21 12:01 ?850次閱讀
    使用鍵盤和LCD顯示屏與<b class='flag-5'>MAXQ2000</b>

    使用MAXQ2000進行音頻濾波

    乘法累加單元(MAC)和單周期內核的組合使MAXQ2000成為多功能微控制(μC)。MAXQ2000具有性能和I/O外設,非常適合許多應用:鬧鐘、手持醫療設備、數字讀數——任何需要低功耗、高性能和大量I/O的應用。通過集成MA
    的頭像 發表于 03-02 14:13 ?935次閱讀
    使用<b class='flag-5'>MAXQ2000</b>進行音頻濾波
    主站蜘蛛池模板: 天堂看动漫| 色综合天天综合网国产人| 色黄污在线看黄污免费看黄污| 国产精品免费久久久免费| 国产精品性| 亚洲第一狼人社区| 天堂tv亚洲tv日本tv欧美人tv| 无人区理论片手机看片| 色老头久久网| 美女网站黄页| 四虎影永久地址www| 四虎影院美女| 欧美videosex性欧美成人| 四虎影院海外永久| 欧美一级特黄aaa大片| 久操福利视频| 美国激情ap毛片| 国产三级日本三级在线播放| www.你懂的| 成年视频在线观看| 国产在线视频资源| 精品国产免费人成高清| 丁香花在线视频| 天天操夜夜逼| 天天干干干| 久久久久免费观看| 牛牛碰在线| 色吧首页dvd| 欧美骚| 99热99操99射| 在线免费亚洲| 亚洲合集综合久久性色 | 午色影院| 天天干夜夜做| 人人爽天天爽夜夜爽曰| 免费网站在线视频美女被| 九九热在线免费| 国产黄大片在线观看| vip影视免费观看| 精品视频一区二区三区| 被男同桌摸内裤好爽视频|