1. 程式人生 > >關於ARM體系中棧的對齊問題

關於ARM體系中棧的對齊問題

基於ARM架構的處理器的C語言程式設計遵循ATPCS(ARM-THUMB procedure call standard)和AAPCS(ARM Application Procedure Call Standard)。ATPCS規定資料棧為FD(滿遞減Full Decrease)型別,並且對資料棧的操作是8位元組對齊的。在我自己的輕量級的嵌入式作業系統tqOS中沒有考慮到執行緒工作棧的8位元組對齊的問題,這樣從記憶體池中分配到的棧的起始地址可能是4位元組對齊的也可能是8位元組對齊的,如果運氣好每一個執行緒的棧式8位元組對齊的則不會有什麼問題出現,如果運氣差執行緒的棧式4位元組對齊的,那麼就會導致種種錯誤......例如,最要命的是線上程函式中進行浮點數運算的時候,兩個浮點數初始化之後打印出來都是錯誤的資料,進行算術運算之後也是錯誤的結果。因為浮點數double是8位元組的,可能非8位元組對齊的棧會導致運算出錯。為了解決這個問題,我在tqOS的任務建立函式中對任務棧空間的分配中做了調整,將棧的起始地址始終設定為8位元組對齊,如果不為8位元組對齊則將棧指標下移至8位元組對齊處。另外,APTCS要求了對棧的操作必須是8位元組對齊的,所以對任務棧的初始化也是有要求的,也就是說一次要入棧兩個資料,或者說一次要入棧偶數個數據,因為一次只入棧一個數據(4位元組長度)的話就會導致棧的地址變成非8位元組對齊了,這是不允許的!C語言程式會由ARM的C編譯器會做好8位元組對齊工作,但是涉及彙編和作業系統的時候就需要自己把握好入棧的資料問題。為此我把棧初始化函式裡面的一個小小的部分改了一下,就是為了保證初始化完棧之後棧頂指標依然為8位元組對齊的(詳見tqOS的修改版的註釋)。