天天看點

流水線和PC

 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,待流水線滿,開始繼續執行