1. 程式人生 > >ARM的三級流水線結構(一)

ARM的三級流水線結構(一)

看到彙編中很多關於程式返回與中斷返回時處理地址都很特別,仔細想想原來是流水線作用的效果。所以,決定總結學習下ARM流水線。

ARM7處理器採用3級流水線來增加處理器指令流的速度,能提供0.9MIPS/MHz的指令處理速度。

PS:

MIPS(Million Instruction Per Second)表示每秒多少百萬條指令。比如0.9MIPS,表示每秒九十萬條指令。

MIPS/MHz表示CPU在每MHz的執行速度下可以執行多少個MIPS,如0.9MIPS/MHz則表示如果CPU執行在1MHz的頻率下,每秒可執行90萬條指令。

如果CPU在20MHz的頻率下,每秒可執行1800萬條指令。MIPS/MHz可以很好的反映CPU的速度。

3級流水線如上圖所示(PC為程式計數器),流水線使用3個階段,因此指令分3個階段執行。

⑴ 取指從儲存器裝載一條指令

⑵ 譯碼識別將要被執行的指令

⑶ 執行處理指令並將結果寫會暫存器

以前學過的51微控制器,因為比較簡單,所以它的處理器只能完成一條指令的讀取和執行後,才會執行下一條指令。這樣,PC始終指向的正在“執行”的指令。

而對於ARM7來說因為是3級流水線,所以把指令的處理分為了上面所述的3個階段。

所以處理時實際是這樣的:ARM正在執行第1條指令的同時對第2條指令進行譯碼,並將第3條指令從儲存器中取出。

所以,ARM7流水線只有在取第4條指令時,第1條指令才算完成執行。

下圖生動形象的說明了3級流水線的處理機制

下面一句話很關鍵:無論處理器處於何種狀態,程式計數器R15(PC)總是指向“正在取指”的指令,而不是指向“正在執行”的指令或者正在“譯碼”的指令。

人們一般會習慣性的將正在執行的指令作為參考點,即當前第1條指令。

所以,PC總是指向第3條指令,

或者說PC總是指向當前正在執行的指令地址再加2條指令的地址。


處理器處於ARM狀態時,每條指令為4個位元組,所以PC值為正在執行的指令地址加8位元組,即是:

PC值 = 當前程式執行位置 + 8位元組

處理器處於Thumb狀態時,每條指令為2位元組,所以PC值為正在執行的指令地址加4位元組,即是:

PC值 = 當前程式執行位置 + 4位元組

下面一個例子就很好的說明了這個問題。

[plain]  view plain copy
  1. 0x4000 ADDPC,PC,#4 ;正在被執行的指令,將地址值PC+4寫入PC 
  2. 0x4004 ...;正在被譯碼的指令 
  3. 0x4008 ...;正在被取指的指令,PC=0x4008 
  4. 0x400C ...;PC+4=0x400C 

另外補充說明就是根據以上描述,流水線只有被指令填滿時才能發揮最大效能,即每時鐘週期完成一條指令的執行(僅單週期指令)。

如果程式發生跳轉,流水線會被清空,這將需要幾個時鐘才能使流水線被再次填滿。因此,儘量地少使用跳轉指令可以提高程式的執行效率

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。


文章來源:http://blog.csdn.net/enlaihe/article/details/7598941