ARM7 LPC2378 遠程升級----軟中斷SWI

ARM7 LPC2378 遠程升級----軟中斷SWI
關於AEM7的軟中斷,這篇文章寫的比較詳細,大家可以深入學習一下:點擊打開鏈接
我在這裏,將我在學習這篇文章時遇到的疑問及理解和大家分享一下
    LPC2300.S文件中的相關軟中斷代碼如下:
    EXPORT    SWI_Handler
    extern  EnableIrqFunc          ;使能中斷函數名,用C語言實現
    extern  DisableIrqFunc         ;禁止中斷函數名,用C語言實現
    SWI_Handler
    STMFD  SP!, {R0,R12,LR}      ;入棧
    LDR      R0, [LR,#-4]        ;取指令
    BIC       R0,R0,#0xFF000000 ;取軟件中斷命令號
    CMP      R0,#0             ;和0比較,因爲我的使能中斷用了軟件中斷命令0,禁止中斷使用了軟件中斷命令1
    BLEQ     EnableIrqFunc     ;爲零調用使能中斷函數
    BLNE    DisableIrqFunc     ;不爲零調用禁止中斷函數
    LDMFD  SP!,{R0,R12,PC}     ;出棧
   我的疑問主要在: STMFD  SP!, {R0,R12,LR}       ;入棧
                    LDR      R0, [LR,#-4]         ;取指令
  入棧的過程怎樣,他是如何入棧的?爲什麼LDR      R0, [LR,#-4]  表示的是取指令?
  入棧的過程:
  ARM規定,sp始終是指向棧頂位置的,STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R0在最低地址,向上依次是R0,R1,R2,...R12,LR。完成後SP指向保存R0的地址
                     

 詳解:對於大多數的設計來說都是把棧底設置在高地址棧頂設置在低地址,即是說上面所說的首先要SP=SP-14×4,這裏理解了之後就好理解了,那麼執行這條指令後,棧中的數據順序從棧底到棧頂爲LR ,R12,R6,R5,R4,R3,R2,R1,R0,此時SP-->R0,即棧頂,這和堆棧的定義沒有衝突,如果SP指向的是LR的話棧就沒有用了哦,其實這裏STMFD有兩種方法處理的:(STMFD的用法詳見上一篇博文)
第一種先計算總共壓入的數據個數,直接一次更改指針SP=SP-4*(number)並從低地址向高地址存入數據
第二種就是每壓入一次就把SP=SP-1*4,同時一個一個的把數據從高地址向低地址壓入
注意點:R0、R1....LR等寄存器是沒有地址的,它們只有保存在裏面的數據,所以如上圖中:LR對應基址-4是將LR裏面的值放入基址減4中,這裏的減4與LDR R0, [LR,#-4]的減4不是同一個概念。
那麼LDR R0, [LR,#-4]爲什麼解釋爲取指令呢?將存儲器地址爲(LR-4)的字數據讀入寄存器R0。
  這裏你必須對ARM7的3級流水線過程做一個瞭解:
  PC 代表程序計數器,流水線使用三個階段,因此指令分爲三個階段執行:
1.取指(從存儲器裝載一條指令);
2.譯碼(識別將要被執行的指令);
3.執行(處理 指令並將結果寫回寄存器)。
  而R15(PC)總是指向“正在取指”的指令,而不是指向“正在執行”的指令或正在“譯碼”的指令。一般來說,人們習慣性約定 將“正在執行的指令作爲參考點”,稱之爲當前第一條指令,因此PC總是指向第三條指令。當ARM狀態時,每條指令爲4字節長,所以PC始終指向該指令地址 加8字節的地址,即:PC值=當前程序執行位置+8;

   ARM指令是三級流水線,取指,譯指,執行時同時執行的,現在PC指向的是正在取指的地址,那麼cpu正在譯指的指令地址是PC-4(假設在ARM狀態 下,一個指令佔4個字節),cpu正在執行的指令地址是PC-8,也就是說PC所指向的地址和現在所執行的指令地址相差8。

   在ARM體系結構中LR的特殊用途有兩種:一是用來保存子程序返回地址;二是當異常發生時,LR中保存的值等於異常發生時PC的值減4(或者減2,對於ARM指令是減4,對於Thumb指令是減2),因此在各種異常模式下可以根據LR的值返回到異常發生前的相應位置繼續執行。 
    在異常發生時,LR保存的是PC-4,而執行指令是PC-8,所以LDR R0, [LR,#-4]解釋爲取指令!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章