0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

在MAXQ2000的數(shù)據(jù)存儲器中實現(xiàn)軟堆棧

星星科技指導(dǎo)員 ? 來源:ADI ? 作者:ADI ? 2023-01-11 11:20 ? 次閱讀

本應(yīng)用筆記演示了一種在數(shù)據(jù)存儲器中實現(xiàn)軟堆棧的簡單方法,用于基于匯編的應(yīng)用。該方法使用MAXQ2000和其他基于MAXQ20的微控制器。示例代碼使用MAX-IDE的宏預(yù)處理功能編寫,MAX-IDE是Maxim基于項目的MAXQ?系列應(yīng)用開發(fā)和調(diào)試環(huán)境。

概述

MAXQ2000微控制器與MaximRISC微控制器系列中的其他MAXQ器件一樣,基于MAXQ20內(nèi)核。基于MAXQ20的微控制器通常實現(xiàn)16位寬的硬件堆棧,其電平數(shù)固定(MAXQ2000為16級),存儲在獨立于數(shù)據(jù)和代碼空間的專用內(nèi)部存儲器中。此硬件堆棧用于在子例程調(diào)用和中斷操作中保存和恢復(fù)微控制器的操作狀態(tài)。

雖然完全適合小型、緊密集中的應(yīng)用程序,但在較大的裝配應(yīng)用程序中使用深度嵌套的子例程(或在堆棧上保存和恢復(fù)多個工作寄存器的子例程)時,硬件堆棧很快就會耗盡空間。用C編程語言編寫的應(yīng)用程序(使用IAR的嵌入式工作臺?等編譯器)或Rowley Associates的MAXQ交叉工作通過利用數(shù)據(jù)存儲器中包含的“軟堆?!眮肀苊膺@個問題。此軟堆棧存儲子例程的調(diào)用/返回地址和本地工作變量。但是,MAXQ20內(nèi)核上沒有內(nèi)置機制來定位數(shù)據(jù)存儲器中的堆棧,可用于僅組裝應(yīng)用。

本應(yīng)用筆記演示了一種在數(shù)據(jù)存儲器中實現(xiàn)軟堆棧的簡單方法,用于基于匯編的應(yīng)用。本應(yīng)用筆記中的代碼可用于MAXQ2000和其他基于MAXQ20的微控制器。示例代碼使用MAX-IDE的宏預(yù)處理功能編寫,MAX-IDE是Maxim基于項目的MAXQ系列應(yīng)用開發(fā)和調(diào)試環(huán)境。

MAX-IDE環(huán)境的最新安裝包和文檔可免費下載

最大 IDE 安裝 (ZIP)

MAXQ磁芯組裝指南 (PDF)

開發(fā)工具指南 (PDF)

MAXQ20內(nèi)核中的硬件堆棧操作

MAXQ20內(nèi)核使用兩種不同類型的堆棧操作:

PUSH 操作(包括操作碼 PUSH、LCALL 和 SCALL)用于在堆棧上存儲數(shù)據(jù)。這些操作將堆棧指針 SP 預(yù)遞增 1,然后將數(shù)據(jù)存儲在 SP 指針 (@SP) 指向的堆棧位置。

POP 操作(包括操作碼 POP、POPI、RE 和 RETI)用于從堆棧中檢索數(shù)據(jù)。這些操作從 SP 指向的堆棧位置檢索數(shù)據(jù),然后將堆棧指針后減 1。

由于硬件堆棧的主要功能之一是在調(diào)用子例程時保存和恢復(fù)地址,因此堆棧由 16 位(字)位置組成。此寬度允許在單次推送或彈出操作中保存或恢復(fù) 16 位指令指針 (IP) 寄存器。即使使用 PUSH 或 POP 將 8 位寄存器(如 AP)保存到堆?;驈亩褩;謴?fù),每個堆棧操作也始終使用整個 16 位字。

除了利用堆棧的各種操作碼外,微控制器還自動使用硬件堆棧的另外兩種情況:

當(dāng)中斷被處理時,當(dāng)前程序執(zhí)行點在中斷服務(wù)例程(由中斷向量寄存器 IV 指向)開始執(zhí)行之前被推送到堆棧上。

當(dāng)調(diào)用某些調(diào)試命令(如讀寄存器和寫入數(shù)據(jù)存儲器)需要執(zhí)行實用程序ROM中的代碼才能完成時,在將控制權(quán)傳輸?shù)綄嵱贸绦騌OM之前,當(dāng)前執(zhí)行點被推送到堆棧上。實用程序 ROM 中的調(diào)試例程完成后,執(zhí)行點將從堆棧中彈出,并恢復(fù)處理器的先前狀態(tài)。

向量到中斷服務(wù)例程或執(zhí)行調(diào)試器命令將始終需要使用硬件堆棧。由于此行為嵌入在硬件中,因此無法解決它。但是,對于更常見的 PUSH/POP 和 CALL/RET 指令對,可以實現(xiàn)軟堆棧。

注意,當(dāng)出現(xiàn)以下任一堆棧錯誤情況時,MAXQ2000(與其它基于MAXQ20內(nèi)核的器件一樣)不提供任何錯誤檢測或警告:

堆棧溢出:當(dāng)值被推送到已經(jīng)滿的堆棧上時發(fā)生。此錯誤會導(dǎo)致堆棧中最舊的值被覆蓋。

堆棧下溢:當(dāng)堆棧為空時,從堆棧中彈出值時發(fā)生。此錯誤會導(dǎo)致返回?zé)o效的數(shù)據(jù)值。例如,如果在堆棧為空時執(zhí)行 RET,則執(zhí)行將轉(zhuǎn)移到不正確(可能是隨機)的地址。

在數(shù)據(jù)存儲器中創(chuàng)建軟堆棧

在數(shù)據(jù)存儲器中創(chuàng)建軟堆棧的第一步是定義將使用數(shù)據(jù)存儲器的哪一部分。然后,必須定義用于跟蹤堆棧頂部當(dāng)前位置的數(shù)據(jù)存儲器指針(DP[0]、DP[1]或BP[Offs])。注意:請注意,應(yīng)用軟件不會將專用于堆棧的數(shù)據(jù)存儲器用于其他目的(例如,變量或緩沖區(qū))。

定義和初始化這種軟堆棧的一種簡單方法涉及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) 寄存器設(shè)置為SS_BASE位置,則可以使用 Offs 寄存器指向堆棧的當(dāng)前頂部。由于 Offs 寄存器只有 8 位寬,因此硬件會自動將堆棧限制在范圍 (BP .(BP+255))在數(shù)據(jù)存儲器中。如果在 Offs 等于 255(溢出)時發(fā)生推送,或者在 Offs 等于 0(下溢)時發(fā)生彈出,則 Offs 寄存器將簡單地繞行到堆棧的另一端。此操作模擬硬件堆棧的運行方式,并允許簡單的軟堆棧實現(xiàn);這不會檢測下溢和溢出情況。

在使用軟堆棧之前,主應(yīng)用程序必須調(diào)用ss_init例程。它將 BP[Offs] 指針設(shè)置為字模式,必須這樣做,因為軟堆棧是作為 16 位寬堆棧實現(xiàn)的。它還將 BP[Offs] 寄存器對指向堆棧的開頭。

軟堆棧操作

使用堆棧的內(nèi)置操作碼(PUSH、POP、CALL、RET等)不能重新定義為使用軟堆棧,因為它們的含義被硬連接到MAXQ匯編器中。此外,可能仍需要在應(yīng)用程序的某些部分(如中斷服務(wù)例程)中使用標準硬件堆棧。由于這些原因,軟堆棧將由復(fù)制標準操作碼的宏訪問。

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

我們現(xiàn)在將討論這些宏是如何工作的。

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 位寄存器中,則寄存器中將僅存儲低字節(jié)。高字節(jié)將丟失。這與內(nèi)置硬件堆棧的行為相同。

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

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

mcall 宏的使用方式與 CALL op 代碼用于執(zhí)行子例程的方式相同。此子例程必須使用 mret 宏(而不是標準 RET 操作代碼)在完成執(zhí)行后返回。

  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

擴展軟堆棧的大小

某些應(yīng)用需要大于 256 個級別的軟堆棧。通過使用其他數(shù)據(jù)指針(DP[0] 或 DP[1])之一,可以實現(xiàn)任何大小的堆棧(最多可達可用數(shù)據(jù)存儲器的限制)。

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

上面顯示的代碼保留數(shù)據(jù)存儲器中的位置 0000h 到 01FFh,從而創(chuàng)建一個最多可容納 511 個級別的堆棧。(堆棧內(nèi)存空間中的一個位置未使用;這允許更短、更高效地實現(xiàn) mpush/mpop/mcall/mret 宏)。

只需更改數(shù)據(jù)指針并將代碼中的其他所有內(nèi)容保留相同即可擴展堆棧。盡管如此,由于DP[0]不限于數(shù)據(jù)存儲器的某個范圍,因此沒有什么可以阻止推送或彈出操作使DP[0]增加或減少到軟堆棧的指定邊界之外。為了避免這種情況,可以添加一些簡單的下溢/溢出檢查。

添加下溢和溢出檢查

為了使宏(每次使用宏時都會擴展為代碼)盡可能短,下溢和溢出檢查在子例程中執(zhí)行,這些子例程由宏使用硬件堆棧調(diào)用。

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

上面的代碼導(dǎo)致在推送或彈出(或調(diào)用或重新)操作發(fā)生之前檢查當(dāng)前堆棧位置。如果檢測到溢出或下溢錯誤,響應(yīng)將因應(yīng)用程序而異。通常,這種錯誤只應(yīng)在應(yīng)用程序開發(fā)期間發(fā)生;如果代碼編寫正確,則不應(yīng)發(fā)生這種情況。如果確實發(fā)生錯誤,通常應(yīng)將其視為致命錯誤,就像在使用硬件堆棧時發(fā)生下溢/溢出一樣。此錯誤的可能響應(yīng)包括停止和傳輸錯誤消息或閃爍 LED。開發(fā)過程中一個有用的技巧是在這兩個例程中的每一個例程中(即,在“錯誤處理程序應(yīng)在此處實現(xiàn)”行)中設(shè)置一個斷點,以便在發(fā)生下溢或溢出時立即反饋。

但是,有時應(yīng)用程序可以從堆棧下溢或溢出中恢復(fù)(例如,通過從頭開始重新加載和重新啟動應(yīng)用程序子任務(wù))。在這種情況下,可能需要簡單地設(shè)置一個標志,指示發(fā)生了堆棧錯誤。此類標志的可能候選者包括位于 PSF 寄存器中的兩個通用標志(GPF0 和 GPF1)。由于有兩個位標志可用,其中一個可用于指示溢出,另一個用于指示下溢。

結(jié)論

MAX-IDE提供強大的宏預(yù)處理功能,允許在MAXQ2000和其他基于MAXQ20的微控制器上直接實現(xiàn)數(shù)據(jù)存儲器中的替換軟堆棧。這種軟堆棧通過允許子例程更加模塊化和可重用來幫助開發(fā)更大的基于程序集的應(yīng)用程序。堆棧還允許檢測基于堆棧的錯誤。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 微控制器
    +關(guān)注

    關(guān)注

    48

    文章

    7555

    瀏覽量

    151429
  • 存儲器
    +關(guān)注

    關(guān)注

    38

    文章

    7492

    瀏覽量

    163848
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1634

    瀏覽量

    49134
收藏 人收藏

    評論

    相關(guān)推薦

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

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

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

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

    MAXQ2000文資料pdf

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

    利用MAXQ2000微控制實現(xiàn)快速傅里葉變換

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

    采用MAXQ2000進行音頻濾波

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

    用uIP堆棧實現(xiàn)MAXQ微控制聯(lián)網(wǎng)-MAXQ2000的應(yīng)用

    用uIP堆棧實現(xiàn)MAXQ微控制聯(lián)網(wǎng) 摘要:本應(yīng)用筆記描述了如何用uIP TCP/IP網(wǎng)絡(luò)協(xié)議棧實現(xiàn)M
    發(fā)表于 08-04 09:47 ?507次閱讀
    用uIP<b class='flag-5'>堆棧</b><b class='flag-5'>實現(xiàn)</b><b class='flag-5'>MAXQ</b>微控制<b class='flag-5'>器</b>聯(lián)網(wǎng)-<b class='flag-5'>MAXQ2000</b>的應(yīng)用

    MAXQ2000數(shù)據(jù)存儲器實現(xiàn)堆棧

    摘要:本應(yīng)用筆記介紹了匯編應(yīng)用數(shù)據(jù)存儲器內(nèi)實現(xiàn)堆棧的簡單方法。該方法使用了
    發(fā)表于 04-23 16:04 ?970次閱讀

    利用MAXQ2000設(shè)計電壓表

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

    利用SD存儲介質(zhì)擴展MAXQ2000的非易失性數(shù)據(jù)存儲空間

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

    采用MAXQ2000進行音頻濾波

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

    采用MAXQ2000微控制和MAX6970 LED驅(qū)動

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

    利用SD存儲介質(zhì)擴展MAXQ2000數(shù)據(jù)存儲空間

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

    MAXQ2000數(shù)據(jù)存儲器實現(xiàn)堆棧

    ),存儲數(shù)據(jù)和程序空間分開的專用內(nèi)部存儲器。通過子程序調(diào)用和中斷,這一硬堆棧可用于保存和恢
    的頭像 發(fā)表于 02-14 18:20 ?811次閱讀

    使用鍵盤和LCD顯示屏與MAXQ2000

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

    使用MAXQ2000進行音頻濾波

    乘法累加單元(MAC)和單周期內(nèi)核的組合使MAXQ2000成為多功能微控制(μC)。MAXQ2000具有性能和I/O外設(shè),非常適合許多應(yīng)用:鬧鐘、手持醫(yī)療設(shè)備、數(shù)字讀數(shù)——任何需要低功耗、高性能和大量I/O的應(yīng)用。通過集成MA
    的頭像 發(fā)表于 03-02 14:13 ?927次閱讀
    使用<b class='flag-5'>MAXQ2000</b>進行音頻濾波