ARM處理器使用流水線來增加處理器指令流的速度,這樣可使幾個操作同時進行,并使處理與存儲器系統之間的操作更加流暢,連續,能提供0.9MIPS/MHZ的指令執行速度。
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。
但是在ADS中PC確實是指向即將執行的指令處,這個是軟件處理后的結果,主要是為了用戶調試程序方便.
需要注意的是,當前使用指令STM/STR保存R15時候,保存的可能是當前指令地址值+8字節,也可能保存的是當前的指令地址+12字節.到底是哪種,取決于芯片的具體的設計方式。無論如何,在同一芯片中,要么采用當前的指令地址+8,要么采用當前的指令地址+12。因此對于用戶來講,盡量避免使用STM/STR指令來保存R15的值。但是可以在開始的時候用一段程序對芯片的offset進行測試!
代碼如下:
SUB R1, PC, #4 ;獲得下面的存放下面存放STR指令的地址
STR PC,[R0]
LDR R0,[RO]
SUB R0, R0, R1
ARM7中斷與PC、LR的問題:
1,假設當前是PC,PC-4,PC-8(三級流水)
2,發生IRQ異常,執行保護操作,LR中保存由于FIQ或IRQ占先而沒有被執行的指令的地址(即有些資料上把這個地址寫成PC或者當前地址,很費解甚至誤解)的下一條地址
3,清空流水線
4,進入中斷服務程序
5,待流水線填滿,執行操作才被重新掛起(解釋了ARM7為什么是0.9MIPS)
6,中斷返回前,對LR處理,LR=LR-4,指向之前被清空的已譯碼但沒被執行的指令的地址
7,清空流水線,返回
8,重新對丟棄的前一次已譯碼指令取指
9,待流水線滿,開始繼續執行
|