ARM 中的lr寄存器


/***********摘自《ARM LR寄存器https://blog.csdn.net/fivedoumi/article/details/50446444》********************/

異常的發生會導致程序正常運行的被打斷, 並將控制流轉移到相應的異常處理(異常響應),有些異常(fiq、irq)事件處理后,系統還希望能回 到當初異常發生時被打斷的源程序斷點處繼續完成源程序的執行(異常返回),這就需要一種解決方案, 用於記錄源程序的斷點位置,以便正確的異常返回。 
    類似的還有子程序的調用和 返回。在主程序中(通過子程序調用指令)調用子程序時,也需要記錄下主程序中的調用點位置,以便將來的子程序的返回。 

 

    在ARM處理器中使用 R14實現對斷點和調用點的記錄,即使用R14用作返 回連接寄存器(LR)。在硬件上和指令執行上,CPU 自動完成相應返回點的記錄。在ARM 匯編語言程序設計時,R14和LR通用。
    ARM處理器相應異常時,會自動完成將當前的PC保存到LR寄存器。//注意:發生異常時進入異常程序時,LR中保存的不是斷點下一條指令,而是直接將PC保存到 LR中,不是將PC-4保存到LR中。
    ARM處理器執行子程序調用指令(BL )時,會自動完成將當前的PC的值減去4的結果數據保存到LR寄存器。即將調用指令的下緊鄰指令的地址保存到LR。
    ARM處理器針對不同的模式,共有6個鏈接寄存器資源(LR ),其中用戶模式和系統模式共用一個 LR,每種異常模式都有各自專用的R14 寄存器(LR )。這些鏈接寄存器分別為 R14、R14_svc、R14_abt、R14_und、R14_irq、R14_fiq,

   程序設計者要清晰處理器的模式與相應寄存器的對應關系,都是使用 R14,但不同模式下的R14 不是同一個物理資源,其內容可能天壤之別。
    R14 不用做鏈接寄存器(LR )時,也可以用做通用數據寄存器。

 

  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。
    當突然發生中斷的時候,保存的是PC的地址
    這樣你就知道了,如果返回的時候返回PC,那么中間就有一個指令沒有執行,所以用SUB pc lr-irq #4

 

 

 

MOV PC,LR

看下面這個ARM匯編吧

BL NEXT ;跳轉到子程序

......... ;NEXT處執行

NEXT

..........

MOV PC,LR ;從子程序返回

這里的BL是跳轉的意思,LR(R14)保存了返回地址

PC(R15)是當前地址,把LR給PC就是從子程序返回

這里有一下總結

首先

1.SP(R13) LR(R14)PC(R15)

2.lr(r14)的作用問題,這個lr一般來說有兩個作用:
1》.當使用bl或者blx跳轉到子過程的時候,r14保存了返回地址,可以在調用過程結尾恢復。
2》.異常中斷發生時,這個異常模式特定的物理R14被設置成該異常模式將要返回的地址。

另外注意pc,在調試的時候顯示的是當前指令地址,而用mov lr,pc的時候lr保存的是此指令向后數兩條指令的地址,大家可以試一下用mov pc,pc,結果得到的是跳轉兩條指令,這個原因是由於arm的流水線造成的,預取兩條指令的結果.

3.子程序返回的三種方法:

 

  1. MOV PC,LR
  2. BL LR
  3. 把R14壓棧再出棧
  • 在子程序入口處使用以下指令將R14存入堆棧
STMFD SP!,{<Regs>,LR}
  • 對應的,使用以下指令可以完成子程序的返回

 

LDMFD SP!, {<Regs>,LR}

 

 

 

深入理解ARM的這三個寄存器,對編程以及操作系統的移植都有很大的裨益。

1、堆棧指針r13(SP):每一種異常模式都有其自己獨立的r13,它通常指向異常模式所專用的堆棧,也就是說五種異常模式、非異常模式(用戶模式和系統模式),都有各自獨立的堆棧,用不同的堆棧指針來索引。這樣當ARM進入異常模式的時候,程序就可以把一般通用寄存器壓入堆棧,返回時再出棧,保證了各種模式下程序的狀態的完整性。

2、連接寄存器r14(LR):每種模式下r14都有自身版組,它有兩個特殊功能。

    (1)保存子程序返回地址。使用BL或BLX時,跳轉指令自動把返回地址放入r14中;子程序通過把r14復制到PC來實現返回,通常用下列指令之一:


                        1、  MOV PC, LR 
                        2、 BX LR

    3、通常子程序這樣寫,保證了子程序中還可以調用子程序。
                         stmfd sp!, {lr}
                         ……
                        ldmfd sp!, {pc}

 

    (2)當異常發生時,異常模式的r14用來保存異常返回地址,將r14如棧可以處理嵌套中斷。

3、程序計數器r15(PC):PC是有讀寫限制的。當沒有超過讀取限制的時候,讀取的值是指令的地址加上8個字節,由於ARM指令總是以字對齊的,故bit[1:0]總是00。當用str或stm存儲PC的時候,偏移量有可能是8或12等其它值。在V3及以下版本中,寫入bit[1:0]的值將被忽略,而在V4及以上版本寫入r15的bit[1:0]必須為00,否則后果不可預測。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM