armcm3權威指南筆記----arm程式設計中地址未對齊方面的影響
P152當使用C開發程式時,推薦開啟CM3的雙字對齊管理機制(在NVIC配置與控制暫存器中,把STKALIGN置位),程式碼形如:
#define NVIC_CCR ((volatile unsigned long *)(0xE000ED14))
*NVIC_CCR = *NVIC_CCR | 0x200; //設定STKALIGN位
STKALIGN 的名詞解釋P306
在響應異常的自動入棧操作時,強制SP對齊到雙字地址上(為什麼要設定STKALIGN位,是因為即使保證棧初始是8位元組對齊的,編譯器也只能保證在呼叫sprintf那個時刻棧是8位元組對齊的但不能保證任意時刻棧都是8位元組對齊的,如果恰巧在MSP沒有8位元組對齊的時刻發生了中斷,而中斷中又呼叫了sprintf,這種情況下仍會出錯
)。修訂版
這是用於確保系統能嚴格遵守AAPCS過程呼叫標準,箇中細節請參閱第12章P181。
上面這段話專門有我的book子目錄下armcm3專案資料子目錄裡的Cortex M3核心版本和堆疊8位元組對齊對uT-Kernel核心移植的影響資料,可以看一下。
ut-kernel中也有在建立任務時,或者
在knl_setup_context強制將棧8位元組對齊。
ssp = tcb->isstack;
/* 8 Byte align ( stack ) */
if ( ((UW)ssp & 0x7) != 0 ) {
ssp = (SStackFrame*)((UW)(ssp)-0x4);
}
因為之前棧已經是4位元組對齊了,所以這個地方做這個操作就可以保證它是8位元組對齊了。
為什麼ut-kernel要在建立新任務時保持任務棧的8位元組對齊啊?因為如果我們保證了棧初始的時候是8位元組對齊的,那麼編譯器可以保證以後呼叫浮點庫時堆疊仍是8位元組對齊的。而呼叫浮點庫函式如在程式中執行以下語句:
sprintf(buf,"%.3f\n\r",fff);前,棧沒八位元組對齊的話,螢幕上顯示列印的浮點資料不正確。
對R13(MSP,PSP)的使用:R13總是32位的。但是在
還有個對ARM對齊思想的認識:
在這個例子裡,我們使用了.ascii和.byte指示字來建立一個零結尾的字串。在定義了字串之後,我們又使用了.align來確保下一條指令會以正確的位置開始。如果不使用.align,彙編器則可能把下一條指令放到未對齊的地址。P259
雙字堆疊對齊方式與異常堆疊幀 P241
在預設情況下,異常堆疊幀會自動對齊到雙字儲存器位置(修訂版2)。早期為修訂版0/1寫的彙編程式,如果要通過堆疊來把資料傳送給異常服務程式,可能會受到影響。為了準確判定堆疊幀的起始位置是否往下挪移了一個字,異常服務例程要先讀取入棧PSR的位元9。如果不想動舊的程式,也可以手工把STKALIGN位元清除,這樣就與以前的一樣了。與EABI標準相容的應用程式不會受影響。這些程式通常是C程式,並且使用與EABI相容的編譯器編譯。