xinzha:
通常來說軟件人員并不關心流水線的細節,尤其是上層軟件程序員,甚至驅動工程師都不需要了解流水線,但是對于一個真正的系統底層工程師來說,了解流水線的一個比較重要的意義就是當出現問題時,能夠精確定位到產生問題的那條指令,從而精確跟蹤問題,還有就是異常處理程序執行完成后根據LR寄存器的值來正確返回也需要對流水線的了解。不過有些情況下體制就不能保證精確定位,比如說有writebuffer的時候,你的寫指令即使會發生錯誤(例如地址錯誤、權限錯誤、器件錯誤等),也是在數個周期之后,當寫指令真正出現在總線上時才會激起異常,其原因是因為速度匹配問題,寫數據需要通過writebuffer來完成,發生異常的時刻已經離發出寫指令的時刻不匹配了。當發生異常的時候,犯罪分子和發生異常時所在模式的pc的匹配關系如下:Dataabortpc-8,因為dataabort只有進入執行階段才能被發現,這時第三條指令已經被取指。IRQpc-8,IRQ發生時刻不可預知,在當前指令執行完之后響應,所以pc也是第三條的地址。FIQpc-8,原理同上。PrefetchAbortpc-4,這個最繞,是預取指時發生錯誤造成的,但是如果這條指令不進入執行階段就不會造成異常,比如說前面一條是jmp。所以我猜測在它進入執行之前,kernel已經知道出錯,pc不再更新,保持為它下一條指令的位置。SWI和UNDEF和上一條一樣,都是在譯碼階段kernel已經知道會發生異常,不再更新pc,但是進入執行階段才會激起異常,所以異常地址也都是pc-4。今天來討論一下對齊問題,在ARM7,即armv4中,規定如果訪問int類型數據時給出的指針地址的低2位不為0的話,系統會自動將低兩位的1抹平,即強制四字節對其,這樣的問題就是如果你的數據偏偏就是不對齊的,cpu拿到的數據就是不正確的,bug由此產生。在ARM9(我接觸的是arm926ejs)中,如果訪問int型數據,低2位不為0,那么cpu直接掛住,一個dataabort。在ARM11之后的版本中支持了非對齊訪問,是在總線上拆分然后拼接來實現的,也就是說如果你訪問int時給出的地址不是4字節對齊,那么總線上會出現兩個int訪問,然后把數據拼接起來送給cpu,這些對于cpu是不可見的,但是會導致速度下降,總線占用率上升。此功能可以通過修改cp15中來關閉,實現跟以前版本一樣的對齊方式。需要說明的是這里的int是4字節而不是2字節。另外一點是對齊問題并不是專指四字節對齊,很多初學者或者有一定經驗的人都會犯這個錯誤,認為只有四字節對齊才會出問題。實際上對齊指的是數據邊界對齊,也就是說longlong數據要8字節對齊,int要4字節對齊,short要2字節對齊,byte自然是怎么對都齊了。