ARM中斷返回PC值分析
在ARM程式的開發過程中,對中斷的處理是很普遍的、也是相當重要的。Realview MDK使用的RVCT編譯器提供了__irq關鍵字,用此關鍵字修飾的函式被作為中斷來函式編譯,即在編譯的過程中,編譯器會自動新增中斷處理過程中現場保護和恢復的程式碼,減小程式的開發難度,加快軟體的開發過程。
在理解__irq關鍵字的作用之前,先看一下ARM核對異常的處理過程。當產生異常時, ARM核拷貝CPSR暫存器的內容SPSR_<mode>暫存器中,同時設定適當的CPSR 位、改變處理器狀態進入ARM 態和處理器模式,從而進入相應的異常模式。在設定中斷禁止位禁止相應中斷(如果需要)後,ARM核保存返回地址到LR_<mode>,同時設定PC為相應的異常向量。當異常返回時, 異常處理需要從SPSR_<mode>暫存器中恢復CPSR的值,同時從LR_<mode>恢復PC,具體的異常返回指令如下:
Ø 從SWI和Undef異常返回時使用:
MOVS PC, LR;
Ø 從FIQ、IRQ和預取終止返回時使用:
SUBS PC, LR,#4;
Ø 從資料異常返回時使用:
SUBS PC, LR,#8
在使用上述指令異常返回時,如果LR之前被壓棧的話使用LDM “∧”, 例如:
LDMFD SP!, {PC}∧
退出異常處理
SWI和未定義指令異常中斷是由當前執行的指令自身產生的。當SWI和未定義指令異常中斷產生時,程式計數器PC的值還未更新,它指向當前指令後面第2條指令(對於ARM指令來說+8位元組;對於Thumb指令來說+4位元組的位置)。當SWI和未定義指令異常中斷產生時,處理器將值(PC-4)儲存到異常模式下的暫存器LR_mode中。這時(PC-4)即指向當前指令的下一條指令地址。因此返回操作可以通過下面的指令來實現:MOV PC,LR
該指令將暫存器LR中的值複製到程式計數器PC中實現程式返回,同時將SPSR_mode暫存器內容複製到當前程式狀態暫存器CPSR中。
在指令預取時,如果目標地址是非法的,該指令將被標記成有問題的指令。這時,流水線上該指令之前的指令繼續執行。當執行到該被標記成有問題的指令時,處理器產生指令預取中止異常中斷。
當發生指令預取中止異常中斷時,程式要返回到該有問題的指令處,重新讀取並執行該指令。因此指令預取中止異常中斷程式應該返回到產生該指令預取中止異常中斷的指令處,而不是返回到發生中斷的指令的下一條指令。
指令預取中止異常中斷是由當前執行的指令自身產生的,當指令預取中止異常中斷產生時,程式計數器PC的值還未更新,它指向當前指令後面第2條指令
該指令將暫存器LR中的值減4後,複製到程式計數器PC中,實現程式返回,同時將SPSR_mode暫存器內容複製到當前程式狀態暫存器CPSR中。
發生資料訪問異常中斷時,程式要返回到該有問題的指令處,重新訪問該資料,因此資料訪問異常中斷應該返回到產生該資料訪問中止異常中斷的指令處,而不是當前指令的下一條指令。
資料訪問異常中斷由當前執行的指令自身產生,當資料訪問異常中斷髮生時,程式計數器pc的值已經更新,它指向當前指令後面第3條指令(對於ARM指令,它指向當前指令地址加12位元組的位置;對於Thumb指令,它指向當前指令地址加6位元組的位置)。此時處理器將值(pc-4)儲存到lr_abt中,它指向當前指令後面第2條指令,所以返回操作可以通過下面指令實現:subs pc, lr, #8
該指令將lr中的值減8後傳給程式計數器pc中,實現程式返回,同時將SPSR_abt暫存器內容複製到當前程式狀態暫存器CPSR中;
通常處理器執行完當前指令後,查詢IRQ中斷引腳,並檢視是否允許IRQ中斷,如果某個中斷引腳有效,並且系統允許該中斷產生,處理器將產生IRQ異常中斷,當IRQ異常中斷產生時,程式計數器pc的值已經更新,它指向當前指令後面第3條指令(對於ARM指令,它指向當前指令地址加12位元組的位置;對於Thumb指令,它指向當前指令地址加6位元組的位置),當IRQ異常中斷產生時,處理器將值(pc-4)儲存到IRQ異常模式下的暫存器lr_irq中,它指向當前指令之後的第2條指令,因此返回操作可以通過下面指令實現:subs pc, lr, #4
與IRQ異常中斷一樣,處理器執行完當前指令後,查詢FIQ中斷引腳,並檢視是否允許FIQ中斷,如果中斷引腳有效,並且系統允許該中斷產生,處理器將產生FIQ異常中斷,當FIQ異常中斷產生時,程式計數器pc的值已經更新,它指向當前指令後面第3條指令(對於ARM指令,它指向當前指令地址加12位元組的位置;對於Thumb指令,它指向當前指令地址加6位元組的位置),當FIQ異常中斷產生時,處理器將值(pc-4)儲存到IRQ異常模式下的暫存器lr_fiq中,它指向當前指令之後的第2條指令,因此返回操作可以通過下面指令實現:subs pc, lr, #4